Enterprise search in Japanese (kuromoji vs n-gram)
KUROMOJIで検索がおかしいと言われた話
ある案件で、
「検索結果がおかしい」
って相談を受けた。
検索文字と一致しない結果が出る、みたいなやつ。
前提
- DB検索ではなく ElasticSearch
- データ量が大きいのでRDBでは対応しない
- 日本語検索
この時点で「まあ難しいやつだな」と思った。
原因はKUROMOJI
調べていくと、原因はシンプルだった。
👉 KUROMOJIを使っていた
KUROMOJIは形態素解析なので、
- 単語単位に分解する
- 文脈ベースで解析する
つまり、
👉 「検索」より「文章理解」に強い
何が起きていたか
例えば、
検索ワードと完全一致してるはずなのに
- 分解のされ方が違う
- トークンが変わる
- 意図しないマッチが起きる
結果、
👉 「なんでこれヒットするの?」
👉 「逆にこれ出てこないの?」
みたいな状態になる。
結論:普通の検索には向いてない
KUROMOJIは強いけど、
👉 一般的な検索(部分一致・曖昧検索)には向いてない
特に業務システムだと
- 完全一致に近い挙動
- 部分一致
- 直感的な検索結果
が求められるので、ズレる。
解決策:n-gramに変更
今回はシンプルに
👉 n-gramに変更
これで
- 部分一致が効く
- ユーザーの期待通りの検索になる
ただし問題はここから
ElasticSearchなので、
👉 analyzerを変える = 再インデックス必須
つまり
- データ入れ直し
- ダウンタイムのリスク
がある。
ALIASで無停止リリース
ここで使ったのが
👉 index alias
手順はこんな感じ👇
- 新しいindex(n-gram)を作る
- データを再投入(reindex)
- 事前に動作確認
- aliasを切り替える
👉 リリースは一瞬
これめちゃくちゃ重要
この方法だと
- 事前にテストできる
- 本番影響なし
- ロールバックも簡単
■ まとめ
- KUROMOJIは「文章解析向き」
- n-gramは「検索向き」
- 日本語検索は用途で使い分けが必要
■ 一言
👉 日本語検索は「技術選定」で9割決まる
■ 余談(実務感)
KUROMOJIはちゃんと理解して使えば強い。
ただ、
「とりあえず日本語だからKUROMOJI」
で入れると、だいたい事故る。