OpenSearchで辞書・類義語を設定する方法

記事タイトルとURLをコピーする

はじめに

こんにちは。 アプリケーションサービス本部の合田です。

OpenSearch で検索精度を向上させたい時、辞書や類義語の設定をする必要がありました。 今回はその設定方法について記載したいと思います。

以降の内容は Amazon OpenSearch Service Version 2.17 で動作確認しています。

実現したいこと

前提として、以下のテキストドキュメントを登録します。

自転車で登坂する

その後、以下のキーワードで検索したときにヒットさせたいと思います。

類義語を設定し、ヒットさせたいキーワード

  • ロードバイク
  • クロスバイク
  • ヒルクライム

辞書を使って「自転車」を単語として認識させ、検索時にヒットするようにしたいキーワード

  • 自転車

デフォルト設定でインデックスを作成し、動作確認

インデックスを作成します。

PUT no_setting_index

ドキュメントを追加します。

PUT no_setting_index/_doc/1
{
  "text": "自転車で登坂する"
}

どのようなトークンで分割されるか確認します。

GET no_setting_index/_termvectors/1?realtime=false
{
  "fields": ["text"],
  "positions": true,
  "offsets": true,
  "payloads": true
}

↓

[ "す", "で", "る", "坂", "登", "自", "転", "車"]

以下クエリで検索しますが何も設定していないため、ヒットしないことが確認できます。

GET no_setting_index/_search
{
  "query": {
    "match": {
      "text": "ロードバイク"
    }
  }
}

辞書・類義語を設定し動作確認

辞書と類義語を設定

日本語に適した分割を行うため、 kuromoji_tokenizer を有効にします。 kuromoji_tokenizer の中に user_dictionary があり、ここで辞書を登録します。

類義語を設定するため、 Synonym token filter の synonyms で類義語を設定します。

PUT synonym_index
{
    "settings": {
        "index": {
            "analysis": {
                "tokenizer": {
                    "kuromoji_user_dict": {
                        "type": "kuromoji_tokenizer",
            "mode": "search",
            "discard_compound_token": true,
            "user_dictionary_rules": [
              "自転車,自転車,ジテンシャ,カスタム名詞",
              "クロスバイク,クロスバイク,クロスバイク,カスタム名詞",
              "ロードバイク,ロードバイク,ロードバイク,カスタム名詞"
            ]
                    }
                },
                "analyzer": {
                    "kuromoji_with_synonym_analyzer": {
                        "type": "custom",
                        "tokenizer": "kuromoji_user_dict",
                        "filter": ["my_synonym_filter"]
                    }
                },
                "filter": {
                    "my_synonym_filter": {
                        "type": "synonym",
            "synonyms": [
              "自転車, ロードバイク, クロスバイク",
              "登坂, ヒルクライム" // 登坂 = ヒルクライム(坂道を登ることを意味)
            ]
                    }
                }
            }
        }
    },
    "mappings": {
        "properties": {
            "text": {
                "type": "text",
                "analyzer": "kuromoji_with_synonym_analyzer",
                "search_analyzer": "kuromoji_with_synonym_analyzer"
            }
        }
    }
}

各項目がどのような設定をしているかは以下の表の通りです。

項目 内容
tokenizer 辞書の設定
analyzer トークン分割の設定
filter 類義語の設定

動作確認

先ほどと同じようにドキュメントを追加します。

PUT synonym_index/_doc/1
{
  "text": "自転車で登坂する"
}

どのようなトークンで分割されるか確認します。

GET synonym_index/_termvectors/1?realtime=false
{
  "fields": ["text"],
  "positions": true,
  "offsets": true,
  "payloads": true
}

↓

["する", "で", "クロスバイク", "ロードバイク", "ヒルクライム", "登坂", "自転車"]

今回は助詞を残した形で動作確認していますが、するなどを削除したい場合は、 kuromoji_part_of_speech token filter などを検討してください。

以下クエリで検索し、辞書を使ってヒットすることが確認できます。

GET synonym_index/_search
{
  "query": {
    "match": {
      "text": "自転車"
    }
  }
}

以下クエリで検索し、類義語を使ってヒットすることが確認できます。

GET synonym_index/_search
{
  "query": {
    "match": {
      "text": "ロードバイク"
    }
  }
}

おわりに

以上が OpenSearch で辞書・類義語を設定する方法でした。

今回は手順を簡略化したかったため、辞書・類義語の設定を手書きしましたが、 Amazon OpenSearch Service のカスタムパッケージを利用することで自動更新できたり運用しやすかったりするのでオススメです。

合田 和樹 (記事一覧)

アプリケーションサービス本部・ディベロップメントサービス1課

自転車に乗ってます