LoginSignup
78
69

More than 5 years have passed since last update.

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

Posted at

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
            }
         ]
      }
   ]
}

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

不明点あり

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

78
69
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
78
69