とあるプロダーツプレイヤーの徒然日記

とあるプロダーツプレイヤーが徒然なるままによしなし事をそこはかとなく書きつくろいます

ElasticSearchでSynonymTokenFilterを設定してみる

概要・背景

最近の若者は、本田翼をばっさーとかって略すらしい。 ホンツバとかって略したくなるのは自分だけでしょうか?

どっちでもいいですが、検索エンジン的には、 本田翼も、ホンツバも、ばっさーも、同じ結果を返して欲しいですよね? もちろん、検索システムを含むサービスの運営側としては、同じ結果を返したいですよね?

日本最大級の医療介護求人サイト | ジョブメドレーではElasticsearchを使っているので、それをうまくチューニングしたというお話。

ElasticSearchについて理解する

Elasticsearchについて無知過ぎたので、そもそもまずは概形を学ぶところからスタート。 以下は、勉強に使った一部の資料。 Elasticsearchチュートリアル - 不可視点 自分流Elasticsearch入門 - $shibayu36->blog; Elasticsearch 日本語で全文検索 その3 — Hello! Elasticsearch. — Medium

わかったこと(今回はこれだけ知っていれば、行ける)

  • データからインデックスを作成して、検索時にクエリを発行して検索する
  • アナライザーは、Toknizerでパースされ、Filterで整理される
  • アナライザーは、インデックス作成用と検索用がある

Ruby on Railsに組み込む

今回、組み込むにあたり、「辞書は定期的にいれかえる必要がある」という要件があった。 そのため、辞書更新の度に、インデックスをすべて更新するのはコストが高いので検索時のanalyzerだけ設定することにした。

辞書ファイルの作成

辞書ファイルの書き方は、大まかに3種類ある。

Synonym Token Filterを参考に

# 下記の用に=>を使うとマッピングされ
# ばっさーと検索すると、本田翼の結果が引っかかる
# ※「ばっさー」の結果は引っかからない
ばっさー => 本田翼

# 下記のようにカンマ(,)でつなげると
# 本田翼やばっさーで、検索すると
# 本田翼とばっさーとほんつばで検索した結果がすべて出る
ばっさー,本田翼,ほんつば

# 複数指定もできる
ばっさー=>ほんつば,本田翼

# 上書き方式ではなく、追加方式
# 下記の例は ばっさー=>ほんつば,本田翼と同じ
ばっさー=>ほんつば
ばっさー=> 本田翼

※追加終わったら、elasticsearchを再起動する

Elasticsearch-inquisitorを使って、実際できているかを見る

elasticsearch-inquisitorプラグインの紹介 - @johtaniの日記 2ndで紹介されているElasticsearch-inquisitorを使い、実際に検索クエリの単語がうまく解釈されているかを確認する。 ※Elasticsearchがきちんと再起動されていることを確認する

検索側のクエリにanalyzerを指定する

Query String Queryを見るとanalyzer: The analyzer name used to analyze the query string.というのがあるので、

{
    'query_string' : {
        'default_field' : 'content',
        'default_operator': 'AND',
        'query' : 'ばっさー',
        'analyzer' : 'search_analyzer',
    }
}

これで検索できる

まとめ

  • elasticsearchで類似語検索する場合は、Synonym Token Filterを使う
  • 基本的には、filterを設定しanalyzerを書いて、elasticsearchを再起動する
  • Query String Queryを使い、analyzerを設定し検索する

以上