# 日本語全文検索について

**URL:** https://discuss.elastic.co/t/topic/69140
**Category:** 日本語による質問・議論はこちら
**Created:** [December 15, 2016, 9:48am UTC](https://discuss.elastic.co/t/topic/69140 "2016-12-15T09:48:43Z")
**Posts on this page:** 6
**Page:** 1

<div class="post-metadata">

### Author: ![tanimoto](https://avatars.discourse-cdn.com/v4/letter/t/dec6dc/32.png) [@tanimoto](https://discuss.elastic.co/u/tanimoto)
#### Post date: [December 15, 2016, 9:48am UTC](https://discuss.elastic.co/t/topic/69140/1 "2016-12-15T09:48:43Z")

</div>

elasticseachのプラグインkuromojiを使用して、日本語をバラバラに分割し、検索を行っているのですが、  
精度がそれほど良くありません。

例 :

```auto
一眼 → 一 と 眼 にわかれる
*kuromojiの検索モードを変えても同じ結果です

```

ユーザー辞書の使用も考えたのですが、対象となるキーワードが無限にあるため、あまり現実的ではないと考えています。

ならば、elasticsearchのクエリでキーワード検索する際に、検索キーワードも同様にanalyzerにかけてしまえば良いのではと考えたのですが、やり方がわかりません。(というかできるのか?)  
参考になるサイトや、方法、または他の良い実現方法をご存知の方がいましたら、ご教授お願いします。

---

<div class="post-metadata">

### Author: ![st1t](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/st1t/32/9188_2.png) [@st1t](https://discuss.elastic.co/u/st1t)
#### Post date: [December 15, 2016, 1:04pm UTC](https://discuss.elastic.co/t/topic/69140/2 "2016-12-15T13:04:50Z")

</div>

見当違いの事を言っていたらすいません。  
どういうインターフェースで検索されるのかよくわかっていないのですが、  
例えばKibanaのDiscover画面のテキストボックスであればダブルクォーテーションで単語を括ってあげるとそれっぽく検索ができているように思います。

- 検索キーワードそのままで検索  

- 検索キーワードをダブルクォーテーションで括った検索

---

<div class="post-metadata">

### Author: ![tanimoto](https://avatars.discourse-cdn.com/v4/letter/t/dec6dc/32.png) [@tanimoto](https://discuss.elastic.co/u/tanimoto)
#### Post date: [December 16, 2016, 1:43am UTC](https://discuss.elastic.co/t/topic/69140/3 "2016-12-16T01:43:09Z")

</div>

ご意見ありがとうございます。

現在、elasticsearchを自身の扱っているwebサイトの検索機能として導入しようと考えています。

なので、検索キーワードはwebからの入力値となります。

入力された値を処理でelasticsearchに投げて、elasticsearchのクエリを生成し、該当データを検索しようと考えています。

elasticsearchは、analyzerを設定するとindex時にすでに文字列を単語区切りに分割するようです。

検索時は分割された文字列の中から該当のキーワードを探しているようなのですが、上記のように「一眼」を「一」と「眼」に分割しているように、一部の文字列がうまくヒットしません。

index時にうまくできないのであれば、同じ方法でキーワードも分割してしまえばヒットするかと考えたのですが。。。

やはりユーザー辞書を使用するほかないのでしょうか・・・

---

<div class="post-metadata">

### Author: ![tsgkdt](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/tsgkdt/32/39151_2.png) [@tsgkdt](https://discuss.elastic.co/u/tsgkdt)
#### Post date: [December 16, 2016, 8:15am UTC](https://discuss.elastic.co/t/topic/69140/4 "2016-12-16T08:15:38Z")

</div>

お使いになられているelasticsearchのバージョンはどれでしょう？

こちらで試した限りですと、5.1.1でkuromojiを設定したフィールドに"私は一眼レフカメラが欲しい"という語を入れて見たところ、  
「一眼」が「一」と「眼」に分かれないのです。

mappingの設定や、どのようなクエリをelasticsearchに発行したのかがわかると良いのですが・・・。  
なお、[検索の精度を上げるアプローチの仕方](https://discuss.elastic.co/t/topic/61728/4)が参考になるかもしれません。

以下、長くなりますがこちらで確認した内容です。

1. 事前準備

indexの作成。 kuromoji\_tokenizerのmodeごとの差異があるかどうかを確認するため、3つAnalyzerを作りました。

- ja-normal-analyzer
- ja-search-analyzer
- ja-extended-analyzer

```auto
PUT kuromoji-test
{
  "template": "kuromoji-test",
  "settings": {
    "analysis": {
      "analyzer": {
        "ja-normal-analyzer": {
          "type": "custom",
          "tokenizer": "ja-normal-tokenizer"
        },
        "ja-search-analyzer": {
          "type": "custom",
          "tokenizer": "ja-search-tokenizer"
        },
        "ja-extended-analyzer": {
          "type": "custom",
          "tokenizer": "ja-extended-tokenizer"
        }
      },
      "tokenizer": {
        "ja-normal-tokenizer": {
          "type": "kuromoji_tokenizer",
          "mode": "normal"
        },
        "ja-search-tokenizer": {
          "type": "kuromoji_tokenizer",
          "mode": "search"
        },
        "ja-extended-tokenizer": {
          "type": "kuromoji_tokenizer",
          "mode": "extended"
        }
      }
    }
  },
  "mappings": {
    "_default_": {
      "dynamic_templates": [
        {
          "test": {
            "match": "message",
            "mapping": {
              "type": "text",
              "fields": {
                "normal": {
                  "type": "text",
                  "analyzer": "ja-normal-analyzer",
                  "term_vector": "with_positions_offsets",
                  "store": true
                },
                "search": {
                  "type": "text",
                  "analyzer": "ja-search-analyzer",
                  "term_vector": "with_positions_offsets",
                  "store": true
                },
                "extended": {
                  "type": "text",
                  "analyzer": "ja-extended-analyzer",
                  "term_vector": "with_positions_offsets",
                  "store": true
                }
              }
            }
          }
        }
      ]
    }
  }
}

```

2.Analyze APIによる分割の確認

```auto
POST kuromoji-test/_analyze
{
  "analyzer": "ja-normal-analyzer",
  "text" : "私は一眼レフカメラが欲しい"
}

```

normal, search, extendedのいずれで行っても 一眼は１つのトークンになりました。  
これはnormalの結果です。

```auto
{
  "tokens": [
    {
      "token": "一眼",
      "start_offset": 0,
      "end_offset": 2,
      "type": "word",
      "position": 0
    },
    {
      "token": "レフ",
      "start_offset": 2,
      "end_offset": 4,
      "type": "word",
      "position": 1
    },
    {
      "token": "カメラ",
      "start_offset": 4,
      "end_offset": 7,
      "type": "word",
      "position": 2
    },
    {
      "token": "が",
      "start_offset": 7,
      "end_offset": 8,
      "type": "word",
      "position": 3
    },
    {
      "token": "欲しい",
      "start_offset": 8,
      "end_offset": 11,
      "type": "word",
      "position": 4
    }
  ]
}

```

3.検索実行による確認

結果が取得できて、またハイライトも行われることを確認しました。（ちゃんと _タグの中に一眼が入っている）_

```auto
PUT kuromoji-test/test/1
{
  "message" : "私は一眼レフカメラが欲しい"
}

```

```auto
GET kuromoji-test/_search
{
  "query": {
    "match_phrase": {
      "message.normal": "一眼"
    }
    
  },
  "highlight": {
    "require_field_match": false,
    "fields": {
      "message.normal" : {},
      "message.search" : {},
      "message.extended" : {}
    }
  }
}

```

```auto
{
  "took": 3,
  "timed_out": false,
  "_shards": {
    "total": 5,
    "successful": 5,
    "failed": 0
  },
  "hits": {
    "total": 1,
    "max_score": 0.28582606,
    "hits": [
      {
        "_index": "kuromoji-test",
        "_type": "test",
        "_id": "1",
        "_score": 0.28582606,
        "_source": {
          "message": "私は一眼レフカメラが欲しい"
        },
        "highlight": {
          "message.search": [
            "私は<em>一眼</em>レフカメラが欲しい"
          ],
          "message.extended": [
            "私は<em>一眼</em>レフカメラが欲しい"
          ],
          "message.normal": [
            "私は<em>一眼</em>レフカメラが欲しい"
          ]
        }
      }
    ]
  }
}

```

---

<div class="post-metadata">

### Author: ![tanimoto](https://avatars.discourse-cdn.com/v4/letter/t/dec6dc/32.png) [@tanimoto](https://discuss.elastic.co/u/tanimoto)
#### Post date: [December 26, 2016, 2:59am UTC](https://discuss.elastic.co/t/topic/69140/5 "2016-12-26T02:59:54Z")

</div>

バージョンを5.1.1に変更したところ解決しました。

---

<div class="post-metadata">

### Author: ![system](https://us1.discourse-cdn.com/elastic/original/3X/1/a/1ac57faf039f6b580b3f104ef42a2a89e41014de.png) [@system](https://discuss.elastic.co/u/system)
#### Post date: [January 23, 2017, 3:00am UTC](https://discuss.elastic.co/t/topic/69140/6 "2017-01-23T03:00:13Z")

</div>

This topic was automatically closed 28 days after the last reply. New replies are no longer allowed.
