✨
Elasticsearchのサジェストで長音に対応したい
課題
Elasticsearch でサジェストを実現するときに、長音を含めた候補がうまく表示されない。
例
「東京」と検索したいとき
t (t)
と (to)
とう (tou)
とうk (touk)
とうky (touky)
とうきょ (toukyo)
とうきょう (toukyou)
東京 (東京)
と入力される。括弧内はひらがなをローマ字に変換したもの。
上記の入力では、最後の「東京」以外は読み仮名のフィールドでヒットしてほしい。
しかし、インデックス時に「東京」は「tokyo」に変換されていたので、
「t」「と」まではヒットしても、「とう」以降はヒットしなかった。
ざっくりとした設定
キーワードをそのまま前方一致させるフィールドと、読み仮名で前方一致させるフィールドを用意する。
今回は、読み仮名で前方一致させるフィールドのみ考える。
読み仮名のインデックス用 analyzer(一部省略)
- tokenizer に kuromoji_tokenizer
- filter に kuromoji_readingform、asciifolding、edge_ngram
読み仮名の検索用 analyzer(一部省略)
- char_filter で mapping を使用し、ひらがな、カタカナをローマ字に変換
解決策
インデックス用の analyzer で、長音を正規化するのではなく、同じ文字を続けるように変換する。「東京」であれば「toukyou」みたいになってほしい。
そのため、kuromoji_readingform でローマ字に直接変換するのではなく、一度カタカナに変換してからローマ字に変換するようにした。
具体的には、kuromoji_readingformのuse_romaji
をfalse
にしてカタカナに変換し、icu_transformのKatakana-Latin
で、ローマ字に変換した。
そうすると、「東京」→「トウキョウ」→「toukyou」と変換されるので、
ひとまず今回の問題は解決できる。
ひとこと
もっといい方法ありそう
Discussion