70
Help us understand the problem. What are the problem?

More than 5 years have passed since last update.

posted at

Elasticsearchで、漢字データでも平仮名でサジェスト取得

Elasticsearchでサジェスト機能を使いたいんだけど、英語でのネタしか見つからなかったので、日本語でサジェストするメモ。

例えば「と」と打って「東京都」が出てきてほしいけど、そのままデータ登録しても「東」じゃないと出てこない。
なので、Kuromojiのカタカナ変換機能を使ってやってみた。

インデックス作成

まずインデックスの作成と設定。(例として「suggest_test」というインデックス名)

// curl -X PUT 'localhost:9200/suggest_test' -d
{
    "settings": {
        "analysis":{
            "analyzer" : {
                "katakana_analyzer" : {
                    "tokenizer" : "kuromoji_tokenizer",
                    "filter" : ["katakana_readingform"]
                }
            },
            "filter" : {
                "katakana_readingform" : {
                    "type" : "kuromoji_readingform",
                    "use_romaji" : false
                }
            }
        }
    }
}

とりあえずサジェスト用のインデックスということで、katakana_analyzerだけ使用。
kuromoji_readingform」というのがカタカナかローマ字に変換するモジュール。
参考) Elasticsearch 日本語で全文検索 その2

マッピング

次にタイプのマッピング。(例として「location」というタイプ名)

// curl -X PUT 'localhost:9200/suggest_test/location/_mapping' -d
{
    "location" : {
        "properties" : {
            "name" : {
                "type" : "string"
            },
            "suggest" : {
                "type" : "completion",
                "index_analyzer" : "katakana_analyzer",
                "search_analyzer" : "katakana_analyzer"
            }
        }
    }
}

サンプルデータ

そしてサンプルデータを入れる。

// curl -X PUT 'localhost:9200/suggest_test/location/1' -d
{
  "name" : "東京都",
  "suggest" : {
    "input": [ "東京都" ],
    "output": "東京都"
  }
}

// curl -X PUT 'localhost:9200/suggest_test/location/2' -d
{
  "name" : "東京都千代田区",
  "suggest" : {
    "input": [ "東京都", "千代田区" ],
    "output": "東京都千代田区"
  }
}

// curl -X PUT 'localhost:9200/suggest_test/location/3' -d
{
  "name" : "千葉県船橋市",
  "suggest" : {
    "input": [ "千葉県", "船橋市" ],
    "output": "千葉県船橋市"
  }
}

これで、Kuromojiが自動的にカタカナに変換して格納してくれる模様。

検索する

クエリを投げてみる。
※「katakana_analyzer」だけど平仮名でもいける

// curl -X POST 'localhost:9200/suggest_test/_suggest?pretty' -d
{
  "location": {
    "text": "",
    "completion": {
      "field": "suggest"
    }
  }
}

結果

{
   "_shards": {
      "total": 5,
      "successful": 5,
      "failed": 0
   },
   "location": [
      {
         "text": "と",
         "offset": 0,
         "length": 1,
         "options": [
            {
               "text": "東京都",
               "score": 1
            },
            {
               "text": "東京都千代田区",
               "score": 1
            }
         ]
      }
   ]
}

サンプルデータを入れる時に「input」の部分を分割して入れたので、以下のような検索でも、

// curl -X POST 'localhost:9200/suggest_test/_suggest?pretty' -d
{
  "location": {
    "text": "",
    "completion": {
      "field": "suggest"
    }
  }
}

「東京都千代田区」はヒットする。

{
   "_shards": {
      "total": 5,
      "successful": 5,
      "failed": 0
   },
   "location": [
      {
         "text": "ち",
         "offset": 0,
         "length": 1,
         "options": [
            {
               "text": "千葉県船橋市",
               "score": 1
            },
            {
               "text": "東京都千代田区",
               "score": 1
            }
         ]
      }
   ]
}

「ち」が頭文字である千葉県が先に出てきてるのもいい感じ。

不明点あり

上記の設定で「と」で「東京都」が引っ張り出せたけど、こんどは 「東」だと出てこない ・・・
これはどうすればいいかいまのところ不明。

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Sign upLogin
70
Help us understand the problem. What are the problem?