mcpField
E
elasticsearch-search-relevance

elasticsearch-search-relevance

github.com/elasticデータ・データベース6021.1k 回インストール今日更新
リポジトリ

elasticsearch-search-relevance について

elastic CLIを使ってElasticsearchの全文検索の関連度を調整するスキルです。コンテンツやカタログのインデックスを管理する人向けに、クエリルールによる固定表示と複数フィールド検索による順位調整を使い分け、変更前後を比較します。

主な機能

  1. 01インデックスマッピングと検索クエリの確認
  2. 02クエリルールによる文書の固定・除外
  3. 03複数フィールド検索による自然順位の調整
  4. 04変更前後の検索結果の比較
  5. 05elastic CLI経由の操作

活用シーン

  1. 01特定クエリで指定商品を先頭に表示
  2. 02タイトルと説明文の検索順位を改善
  3. 03複数語クエリの再現率を調査

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/elastic/agent-skills --skill elasticsearch-search-relevance

インストール後、Claude Code で/elasticsearch-search-relevanceを入力して読み込まれたか確認します。

同梱ファイルreferences/multi-match-tuning.mdreferences/query-rules-reference.md

詳細

Elasticsearch 検索関連性

コンテンツインデックスとカタログインデックスの全文検索結果を改善します。マッピングと現在のクエリを診断し、適切な関連性調整方法(決定的な固定表示にはクエリルール、自然なランキングには multi_match とフィールドブースト)を選択して変更を適用し、上位のヒットを確認してから成功を報告します。

環境設定

このスキルは elastic CLI を使用して Elasticsearch の操作を実行します。 elastic CLI がインストールされていない場合は、何に必要なのかをユーザーに伝えてください。認証情報を推測したり、HTTP API を直接呼び出したり、ほかの回避策を試したりしないでください。

このスキルでは、HTTP 短縮形式(例:GET /、GET /_cat/indices、GET /{index}/_mapping、 GET /{index}/_settings/index.mode、POST /_query)で操作を記載しています。このドキュメントの最後にある 操作テーブルでは、各短縮形式に対応する elastic CLI コマンドを示しています。HTTP API を直接呼び出すのではなく、必ず CLI を使用してください。

対象範囲

このスキルでは、text フィールド(および任意の keyword フィールド)を持つインデックス(商品カタログ、ドキュメント、ナレッジベースなど)の Query DSL 関連性を扱います。評価には POST /{index}/_search を使用し、固定表示または除外するドキュメントにはクエリルール API を使用します。

対象外:

  • ES|QL 検索(POST /_query) — elasticsearch-esql スキルを使用してください。
  • セマンティック検索/ベクトル検索/ハイブリッド検索 — 異なるフィールドタイプとリトリーバーを使用します。
  • テキストの関連性を改善するのではなく、価格、日付、人気度で並べ替えること。ただし、ユーザーが明示的に関連性以外の並び順を希望している場合を除きます。

関連性の調整方法

ユーザーの意図調整方法API
クエリ Q でドキュメント X を常に最初に表示するクエリルール — pinned ルールと検索時の rule クエリPUT /_query_rules/{ruleset_id}, POST /{index}/_search
クエリ Q で特定のドキュメントを非表示にするクエリルール — exclude ルールと rule クエリ同上
自由形式のテキストクエリのランキングを改善するマッピングされた text フィールドを対象とする multi_match とフィールドブーストPOST /{index}/_search
ユーザーの言語に一致しないトークンOperator、minimum_should_match、または同義語アナライザーPOST /{index}/_search、必要に応じて POST /{index}/_analyze

判断基準: 特定のクエリで最初に表示する必要のあるドキュメントをユーザーが指定した場合は、クエリルールを使用します。フレーズに対する結果全般の品質が低い場合は、マッピングをもとに自然なクエリを調整します。極端なブースト、function_score、ソート句を使って固定表示を再現しないでください。

手順

  1. マッピングと現在のクエリを調べます。 GET / を呼び出して接続を確認します。インデックスが不明な場合は、GET /_cat/indices で候補を絞り込んでから、GET /{index}/_mapping を呼び出します。

    マッピングから、すべての text フィールド(例:title、description)と、フィルターに使用するすべての keyword フィールド(brand、category)を列挙します。どのフィールドが短いか(適合率)、長いか(再現率)も確認します。ユーザーが現在の検索ボディを提示している場合は、その内容を読み、どのフィールドを検索しているか、また rule、multi_match、単一フィールドの match のいずれをすでに使用しているかを特定します。

    判断: 問題は決定的な昇格(1 つのクエリで 1 つのドキュメントを必ず上位にすること)ですか、それとも自然なランキング(複数のドキュメントのスコアを改善すること)ですか。必要なデータ: インデックス名、マッピングのプロパティ、現在のクエリ JSON、クエリ文字列の例、固定表示する場合は対象ドキュメント ID。

  2. 関連性を高める手段を選びます。 手順 1 の判断を適用します。

    • ピン留め/プロモーション → pinned タイプのルールを含むクエリルールのルールセットを作成します(プロモーションに exclude を使ってはいけません)。ルールが意図したクエリテキストに対してのみ発動するように criteria を設定します。たとえば、query_string のようなメタデータキーに対して、値を "sale" とした contains または exact を使います。actions は、ids(例:["SKU123"])または docs(例:[{"_index":"catalog","_id":"SKU123"}])で正しいドキュメントをピン留めするように設定します。インデックス間で _id が一意でない可能性がある場合は、docs を使います。完全な構造については、クエリルールリファレンスをお読みください。

    • オーガニックランキング → 長いフィールドに対する単一フィールドの match を、マッピングされた text フィールド全体に対する multi_match に置き換えます。短いフィールドをブーストします(通常は title^2 とし、description はブーストしません)。複数語の再現率が依然として低い場合は、operator、minimum_should_match、または同義語対応のアナライザーを検討します。ただし、テキストの関連性を高く見せるために価格、日付、キーワードフィールドでソートしてはいけません。また、解析対象のユーザーフレーズに対して .keyword サブフィールドを term でクエリしてはいけません。Multi-Match のチューニングをお読みください。

    判断: リクエストごとに、主要な手段を必ず 1 つ選びます。必要なデータ: 選択したフィールドとブースト、ルールセット ID とルール ID の名前、criteria のメタデータキー、ピン留めするドキュメントの識別子。

  3. 変更を適用します。 選択した手段に応じて API を実行します。

    クエリルールの手順

    • PUT /_query_rules/{ruleset_id} でルールセットを作成または置き換えます(または、PUT /_query_rules/{ruleset_id}/_rule/{rule_id} でルールを 1 つ追加します)。
    • GET /_query_rules/{ruleset_id} で構造を確認します。
    • 検索時に渡すものと同じ match_criteria を使い、POST /_query_rules/{ruleset_id}/_test で criteria を検証します。
    • 検索に組み込みます: POST /{index}/_search では、ruleset_id がルールセットを参照し、match_criteria がすべての criteria の metadata キーに値を指定する rule クエリを使う必要があります(例:"query_string": "sale")。通常の関連性句は organic の中に配置します。ルールセットを作成しただけでは何もピン留めされません — ピン留めが適用されるのは、検索に rule クエリが含まれている場合のみです。

    オーガニックチューニングの手順

    • マッピングをもとに、候補となる multi_match(または同等の bool/should)クエリを作成します。
    • トークン化によって結果の欠落を説明できる場合は、サンプルクエリテキストに対して POST /{index}/_analyze を実行し、解析結果を確認します(任意)。

    判断: 一貫性のある変更セットを 1 つ適用したら、それ以上進めずにテストします。テスト前に無関係な編集を積み重ねないでください。

  4. テストし、上位ヒットを比較します。 候補ごとに、変更前と変更後で同じ size(10 以上)、ユーザーのクエリ文字列、および "track_scores": true を指定して POST /{index}/_search を呼び出します。ピン留めの場合、検索ボディには手順 3 の rule クエリを必ず含めます。

    各実行について、次の項目を比較します。

    • 上位の _id 値と順序
    • 関連する場合は _score
    • 主な _source フィールド(title、description、商品 ID)

    ピン留めの場合、match_criteria がクエリに一致すると、対象ドキュメント(例:SKU123)が先頭に表示され、その下にオーガニックな一致結果が表示されることを確認します。オーガニックチューニングの場合、ソートやキーワードの完全一致を利用した小細工に頼らず、タイトルと意図に合ったドキュメントの順位が上がることを確認します。

    判断: エビデンスに基づいて最良の候補を採用します。どの候補も結果を改善しない場合は、試した内容を報告し、次の手段(同義語やフィールドの追加など)を提案します。必要なデータ: ベースラインクエリと候補クエリの上位ヒットリストを並べた比較。

例

catalog でクエリ「sale」に対して SKU123 をピン留めする

誤り: SKU123 をブーストする、_id でソートする、または rule 検索クエリを指定せずにルールセットを作成する。

正しい方法:

  1. pinned ルールを含む PUT /_query_rules/catalog-sale-pin を実行します。criteria はクエリテキスト "sale" に一致させ、actions は SKU123 をピン留めします。
  2. 次の内容で POST /catalog/_search を実行します。
{
  "query": {
    "rule": {
      "ruleset_id": "catalog-sale-pin",
      "match_criteria": { "query_string": "sale" },
      "organic": {
        "multi_match": {
          "query": "sale",
          "fields": ["title^2", "description"]
        }
      }
    }
  },
  "size": 10
}

SKU123 が 1 件目にヒットし、残りのヒットがピン留めされた結果の下にオーガニックな一致結果として表示されることを確認します。

description のみが検索される場合に「running shoes」を改善する

マッピングでは、title と description は text、brand と category は keyword として定義されています。

誤り: description のみを対象とする match を維持し、価格順に並べ替え、title.keyword に対して term クエリを使用します。

正しい方法:

  1. ベースライン:ユーザーが現在使用している description に対する match を使って POST /catalog/_search を実行し、上位のヒットを記録します。
  2. 候補:次の内容で POST /catalog/_search を実行します。
{
  "query": {
    "multi_match": {
      "query": "running shoes",
      "fields": ["title^2", "description"],
      "type": "best_fields",
      "operator": "or",
      "minimum_should_match": "75%"
    }
  },
  "size": 10
}
  1. 上位のヒットを比較します。title に「running shoes」を含むドキュメントは、description のみに一致するドキュメントより上位に表示されるはずです。それでも再現率が低い場合は、後続のイテレーションで同義語の展開を検討します(価格順への並べ替えではありません)。

ガイドライン

  • すべてのフィールド名をマッピングに基づいて指定する — GET /{index}/_mapping を確認せずに、name、content、body を決して作り出さないでください。
  • ピン留めにはクエリルール、ランキングにはブースト — マーチャンダイジングはクエリルールで行い、フィールドのブーストはオーガニック検索クエリで行います。
  • マッチ条件の連携は必須 — ルール条件の metadata キーは、実行時の値(通常はユーザーのクエリ文字列)とともに、検索の rule.match_criteria オブジェクトに含める必要があります。
  • 成功を主張する前にテストする — ベースライン検索と候補検索を実行し、上位ヒットの変化を示します。
  • keyword フィールドはフィルタリング、text フィールドは検索に使う — 自然言語の主な全文検索対象としてではなく、filter コンテキストで keyword フィールドを使用します。
  • 必ず具体的な成果物を提供する — 検証のためにクラスターへ接続できない場合でも、完全なルールセット JSON(ピン留め用)または候補クエリ本文(オーガニック検索の調整用)を作成し、接続が利用可能になった後の検証方法を説明します。概要だけで終わらせないでください。

参考資料

操作

HTTP API(省略形)elastic CLI コマンド
GET /elastic es info
GET /_cat/indiceselastic es cat indices --index '<pattern>'
GET /{index}/_mappingelastic es indices get-mapping --index '<index>'
PUT /_query_rules/{ruleset_id}elastic es query-rules put-ruleset --ruleset-id '<id>' --rules '<json>'
PUT /_query_rules/{ruleset_id}/_rule/{rule_id}elastic es query-rules put-rule --ruleset-id '<id>' --rule-id '<id>' --type pinned --criteria '<json>' --actions '<json>'
GET /_query_rules/{ruleset_id}elastic es query-rules get-ruleset --ruleset-id '<id>'
POST /_query_rules/{ruleset_id}/_testelastic es query-rules test --ruleset-id '<id>' --match-criteria '<json>'
POST /{index}/_searchelastic es search --index '<index>' --query '<json>'
POST /{index}/_analyzeelastic es indices analyze --index '<index>' --field '<field>' --text '<text>'

コメント