<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0">
  <channel>
    <title><![CDATA[Mike Pellegrini - Elasticsearch Labs]]></title>
    <description><![CDATA[Articles and tutorials from the Search team at Elastic]]></description>
    <copyright><![CDATA[© 2026. Elasticsearch B.V. All Rights Reserved]]></copyright>
    <image>
      <title><![CDATA[Mike Pellegrini - Elasticsearch Labs]]></title>
      <url>https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt1121c0bf0e8a6e65/6a88da6340a1841030ef456f/search-labs-thumbnail.png</url>
      <link>https://www.elastic.co/jp/search-labs/author/mike-pellegrini</link>
    </image>
    <link>https://www.elastic.co/jp/search-labs/author/mike-pellegrini</link>
    <atom:link href="https://www.elastic.co/jp/search-labs/rss/author/mike-pellegrini.xml" rel="self" type="application/rss+xml"/>
    <language><![CDATA[jp]]></language>
    <lastBuildDate>Mon, 05 Oct 2026 17:56:23 GMT</lastBuildDate>
  <item>
    <title><![CDATA[面倒な手間を省いたハイブリッド検索：リトリーバーによるハイブリッド検索の簡素化]]></title>
    <description><![CDATA[線形および RRF リトリーバーのマルチフィールド クエリ形式を使用して Elasticsearch でのハイブリッド検索を簡素化する方法と、Elasticsearch インデックスに関する事前の知識なしでクエリを作成する方法について説明します。]]></description>
    <content:encoded><![CDATA[<p><a href="https://www.elastic.co/what-is/hybrid-search">ハイブリッド検索は</a>、<a href="https://www.elastic.co/search-labs/blog/lexical-and-semantic-search-with-elasticsearch#lexical-search---sparse-retrieval">語彙検索</a>の精度と速度と<a href="https://www.elastic.co/what-is/semantic-search">セマンティック検索</a>の自然言語機能を組み合わせた強力な検索アプローチとして広く認識されています。ただし、実際に適用するのは難しい場合があり、インデックスに関する深い知識と、単純ではない構成での詳細なクエリの構築が必要になることがよくあります。このブログでは、<a href="https://www.elastic.co/docs/reference/elasticsearch/rest-apis/retrievers#multi-field-query-format">リニア リトリーバーと RRF リトリーバーのマルチフィールド クエリ形式によって</a>ハイブリッド検索がよりシンプルで使いやすくなり、よくある問題点が解消され、より簡単にその全機能を活用できるようになる方法について説明します。また、マルチフィールド クエリ形式を使用すると、インデックスに関する事前の知識がなくてもハイブリッド検索クエリを実行できる方法についても説明します。</p><h2>スコア範囲の問題</h2><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt3521a6558cd477ca/6a17f174445de94d3c4d0225/c8b49153c47d2cdc233c0d2e440db04711d48ca5-1600x1600.jpg" alt="" /><p>まず最初に、ハイブリッド検索が困難になる主な理由の 1 つである、スコア範囲の多様性について確認しましょう。私たちの古い友人<a href="https://www.elastic.co/elasticon/conf/2016/sf/improved-text-scoring-with-bm25">BM25</a>は無制限のスコアを生成します。言い換えれば、BM25 は 0 に近い値から (理論的には) 無限大までの範囲のスコアを生成できます。対照的に、 <code>dense_vector</code>フィールドに対するクエリでは、0 から 1 の範囲のスコアが生成されます。この問題をさらに悪化させるのは、 <code>semantic_text</code>埋め込みのインデックス作成に使用されるフィールド タイプが難読化されるため、インデックスと推論エンドポイントの構成に関する詳細な知識がない限り、クエリのスコアの範囲がどうなるかを判断するのが難しい場合があることです。これは、語彙検索結果と意味検索結果をインターリーブしようとするときに、意味検索結果の関連性が高い場合でも、語彙検索結果が意味検索結果よりも優先される可能性があるため、問題が発生します。この問題に対する一般的に受け入れられている解決策は、結果をインターリーブする前にスコアを正規化することです。Elasticsearch には、これを実行するためのツールとして、<a href="https://www.elastic.co/docs/reference/elasticsearch/rest-apis/retrievers/linear-retriever">線形リトリーバー</a>と<a href="https://www.elastic.co/docs/reference/elasticsearch/rest-apis/retrievers/rrf-retriever">RRF</a>リトリーバーの 2 つがあります。
</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt09ed6bf3d25066bd/6a17f1750b0bedbd70dd3686/264481268c8b6ac259e3c257b85431b513f16672-1077x586.png" alt="線形/RRFを使用した場合と使用しない場合の検索結果の比較" /><p><strong>RRF</strong>リトリーバーは、ドキュメントのランクを関連性の尺度として使用し、スコアを破棄して、 <a href="https://www.elastic.co/docs/reference/elasticsearch/rest-apis/reciprocal-rank-fusion">RRF アルゴリズム</a>を適用します。スコアは考慮されないため、スコア範囲の不一致は問題になりません。</p><p><strong>線形</strong>リトリーバーは線形結合を使用してドキュメントの最終スコアを決定します。これには、ドキュメントの各コンポーネント クエリのスコアを取得し、それを正規化し、合計して合計スコアを生成することが含まれます。数学的には、この操作は次のように表現できます。</p>Total Score = 𝚺(N(Sx))<p>ここで、 <code>N</code>は正規化関数であり、SX はクエリ X のスコアです。ここで重要なのは正規化関数です。正規化関数は各クエリのスコアを同じ範囲を使用するように変換します。リニア リトリーバーの詳細については、<a href="https://www.elastic.co/search-labs/blog/linear-retriever-hybrid-search">こちらを</a>ご覧ください。</p><h2>詳しく見てみる</h2><p>ユーザーはこれらのツールを使用して効果的なハイブリッド検索を実装できますが、インデックスに関するある程度の知識が必要です。線形リトリーバーを使用して、2 つのフィールドを持つインデックスをクエリする例を見てみましょう。</p>PUT linear_retriever_example
{
  "mappings": {
    "properties": {
      "semantic_text_field": { &lt;1&gt;
        "type": "semantic_text",
        "inference_id": ".multilingual-e5-small-elasticsearch"
      },
      "text_field": { &lt;2&gt;
        "type": "text"
      }
    }
  }
}<p>1. <code>semantic_text_field</code>は、テキスト埋め込みモデルである<a href="https://www.elastic.co/docs/explore-analyze/machine-learning/nlp/ml-nlp-e5">E5</a>を使用する<code>semantic_text</code>フィールドです。</p><p>2. <code>text_field</code>は標準の<code>text</code>フィールドです</p>GET linear_retriever_example/_search
{
  "retriever": {
    "linear": {
      "retrievers": [
        {
          "retriever": {
            "standard": {
              "query": {
                "match": { &lt;1&gt;
                  "semantic_text_field": "foo"
                }
              }
            }
          },
          "normalizer": "minmax"
        },
        {
          "retriever": {
            "standard": {
              "query": {
                "match": {
                  "text_field": "foo"
                }
              }
            }
          },
          "normalizer": "minmax"
        }
      ]
    }
  }
}<p>1. <a href="https://www.elastic.co/search-labs/blog/semantic-search-match-knn-sparse-vector#we-made-match-happen-in-semantic-search!">Elasticsearch 8.18/9.0でサポートされた</a><code>semantic_text</code>フィールドで<code>match</code>クエリを使用します。</p><p>
クエリを構築するときは、 <code>semantic_text_field</code>テキスト埋め込みモデルを使用するため、このクエリでは 0 から 1 の間のスコアが生成されることに留意する必要があります。また、 <code>text_field</code>は標準の<code>text</code>フィールドであるため、これに対するクエリによって無制限のスコアが生成されることも知っておく必要があります。適切な関連性を持つ結果セットを作成するには、クエリ スコアを結合する前に正規化するリトリーバーを使用する必要があります。この例では、 <code>minmax</code>正規化を備えた線形リトリーバーを使用して、各クエリのスコアを 0 から 1 の間の値に正規化します。</p><p>この例のクエリ構築は、関係するフィールドが 2 つだけなので、非常に簡単です。ただし、さまざまなタイプのフィールドが追加されると、すぐに複雑になる可能性があります。これは、効果的なハイブリッド検索クエリを記述するには、クエリ対象のインデックスに関するより深い知識が必要になることが多く、組み合わせる前にコンポーネント クエリ スコアが適切に正規化される必要があることを示しています。これは、ハイブリッド検索のより広範な導入の障害となります。</p><h3>クエリのグループ化</h3><p>例を拡張してみましょう。1 つの<code>text</code>フィールドと 2 つの<code>semantic_text</code>フィールドをクエリしたい場合はどうなるでしょうか。次のようなクエリを作成できます。</p>GET linear_retriever_example/_search
{
  "retriever": {
    "linear": {
      "retrievers": [
        {
          "retriever": {
            "standard": {
              "query": {
                "semantic": {
                  "field": "semantic_text_field_1",
                  "query": "foo"
                }
              }
            }
          },
          "normalizer": "minmax"
        },
        {
          "retriever": {
            "standard": {
              "query": {
                "semantic": {
                  "field": "semantic_text_field_2",
                  "query": "foo"
                }
              }
            }
          },
          "normalizer": "minmax"
        },
        {
          "retriever": {
            "standard": {
              "query": {
                "match": {
                  "text_field": "foo"
                }
              }
            }
          },
          "normalizer": "minmax"
        }
      ]
    }
  }
}<p>表面的には良さそうですが、潜在的な問題があります。これで、 <code>semantic_text</code>フィールドの一致が合計スコアの 2/3 を占めることになります。</p>Total Score = N(semantic_text_field_1 score) + N(semantic_text_field_2 score) + N(text_field score)<p>これは、不均衡なスコアを作成するため、おそらく望ましい結果ではありません。この例のようにフィールドが 3 つしかない場合、影響はそれほど顕著ではないかもしれませんが、より多くのフィールドをクエリすると問題が生じます。例えば、ほとんどの索引には意味フィールド（つまり<code>dense_vector</code> 、 <code>sparse_vector</code> 、または<code>semantic_text</code> )。上記のパターンを使用して、9 つの語彙フィールドと 1 つの意味フィールドを持つインデックスをクエリするとどうなるでしょうか?語彙の一致がスコアの 90% を占めることになり、意味検索の有効性が鈍ってしまいます。</p><p>これに対処する一般的な方法は、クエリを語彙と意味のカテゴリにグループ化し、その 2 つに均等に重み付けすることです。これにより、どちらかのカテゴリーが合計スコアを支配することが防止されます。</p><p>それを実践してみましょう。この例では、線形リトリーバーを使用する場合、グループ化されたクエリのアプローチはどのようになるでしょうか?</p>GET linear_retriever_example/_search
{
  "retriever": {
    "linear": {
      "retrievers": [
        {
          "retriever": {
            "linear": {
              "retrievers": [
                {
                  "retriever": {
                    "standard": {
                      "query": {
                        "semantic": {
                          "field": "semantic_text_field_1",
                          "query": "foo"
                        }
                      }
                    }
                  },
                  "normalizer": "minmax"
                },
                {
                  "retriever": {
                    "standard": {
                      "query": {
                        "semantic": {
                          "field": "semantic_text_field_2",
                          "query": "foo"
                        }
                      }
                    }
                  },
                  "normalizer": "minmax"
                }
              ]
            }
          },
          "normalizer": "minmax"
        },
        {
          "retriever": {
            "standard": {
              "query": {
                "match": {
                  "text_field": "foo"
                }
              }
            }
          },
          "normalizer": "minmax"
        }
      ]
    }
  }
}<p>うわー、これは冗長になってきましたね!クエリ全体を確認するには、上下に何度もスクロールする必要があったかもしれません。ここでは、2 つのレベルの正規化を使用してクエリ グループを作成します。数学的には次のように表現できます。</p>Total Score = N(N(semantic_text_field_1 score) + N(semantic_text_field_2 score)) + N(text_field score)<p>この 2 番目のレベルの正規化により、 <code>semantic_text</code>フィールドと<code>text</code>フィールドに対するクエリが均等に重み付けされるようになります。この例では、語彙フィールドが 1 つしかないため、 <code>text_field</code>の 2 番目のレベルの正規化を省略し、冗長性を<em>さらに</em>軽減していることに注意してください。</p><p>このクエリ構造はすでに扱いにくく、クエリするフィールドは 3 つだけです。より多くのフィールドをクエリするにつれて、熟練した検索実践者にとっても管理がますます困難になります。</p><h2>複数フィールドのクエリ形式</h2><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt5d9007d279f0da29/6a17f17714d90c39cf79b6f5/dd04e1686076a574b717c1460acfe4eb79299208-1600x1600.jpg" alt="" /><p>これらすべてを簡素化するために、Elasticsearch 8.19、9.1、 サーバーレスの 線形および RRF リトリーバーに<a href="https://www.elastic.co/cloud/serverless"> マルチフィールド</a><a href="https://www.elastic.co/docs/reference/elasticsearch/rest-apis/retrievers#multi-field-query-format"> クエリ形式</a> を追加しました。次のようにするだけで、上記と同じクエリを実行できます。</p>GET linear_retriever_example/_search
{
  "retriever": {
    "linear": {
      "fields": [ "semantic_text_field_1", "semantic_text_field_2", "text_field" ],
      "query": "foo",
      "normalizer": "minmax"
    }
  }
}<p>これにより、クエリが 55 行から 9 行に短縮されます。Elasticsearch はインデックス マッピングを自動的に使用して次の処理を実行します。</p><ul><li><p>クエリされた各フィールドのタイプを決定する</p></li><li><p>各フィールドを語彙または意味のカテゴリにグループ化します</p></li><li><p>最終スコアでは各カテゴリーを均等に重み付けする</p></li></ul><p>これにより、使用されるインデックスや推論エンドポイントの詳細を知らなくても、誰でも効果的なハイブリッド検索クエリを実行できるようになります。</p><p>RRF を使用する場合、ランクは関連性の代理として使用されるため、 <code>normalizer</code>を省略できます。</p>GET rrf_retriever_example/_search
{
  "retriever": {
    "rrf": {
      "fields": [ "semantic_text_field_1", "semantic_text_field_2", "text_field" ],
      "query": "foo"
    }
  }
}<h2>フィールドごとのブースティング</h2><p>リニア リトリーバーを使用する場合、フィールドごとにブーストを適用して、特定のフィールドでの一致の重要度を調整できます。たとえば、2 つの<code>semantic_text</code>フィールドと 2 つの<code>text</code>フィールドの 4 つのフィールドをクエリするとします。</p>GET linear_retriever_example/_search
{
  "retriever": {
    "linear": {
      "fields": [ "semantic_text_field_1", "semantic_text_field_2", "text_field_1", "text_field_2" ],
      "query": "foo",
      "normalizer": "minmax"
    }
  }
}<p>デフォルトでは、各フィールドはグループ内（語彙または意味）で均等に重み付けされます。スコアの内訳は次のようになります。</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltdc6e197e5ff7b68d/6a17f179505ac32834ad8c46/ba31c76189e3a1e5b1638437ccf0528aafec2598-1600x549.png" alt="クエリグループとフィールドスコアの比較" /><p>つまり、各フィールドは合計スコアの 25% を占めます。</p><p><code>field^boost</code>構文を使用して、任意のフィールドにフィールドごとのブーストを追加できます。<code>semantic_text_field_1</code>と<code>text_field_1</code>に2のブーストを適用してみましょう。</p>GET linear_retriever_example/_search
{
  "retriever": {
    "linear": {
      "fields": [ "semantic_text_field_1^2", "semantic_text_field_2", "text_field_1^2", "text_field_2" ]
      "query": "foo",
      "normalizer": "minmax"
    }
  }
}<p>スコアの内訳は次のようになります。</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltccc9ed7d6e865a5e/6a17f17abe6086a31d004882/de20e555d52f914bf483a048d056f54f4fece757-1600x549.png" alt="refとハイブリッド検索でフィールドの重みを変更しました" /><p>各クエリ グループの重みは均等ですが、グループ内のフィールドの重みは次のように変更されました。</p><ul><li><p><code>semantic_text_field_1</code> セマンティッククエリグループスコアの66％、合計スコアの33％</p></li><li><p><code>text_field_1</code> 語彙質問グループスコアの66％、総スコアの33％</p></li></ul><p>ℹ️ フィールドごとのブーストを適用しても、合計スコアの範囲は変更されないことに注意してください。これはスコア正規化の意図された副作用であり、語彙クエリスコアと意味クエリスコアが互いに直接比較可能のままになることを保証します。</p><p>ℹ️ フィールドごとのブースティングは、Elasticsearch 9.2 以降の RRF リトリーバーでも使用できます。</p><h3>ワイルドカード解決</h3><p>複数のフィールドを一致させるには、 <code>fields</code>パラメータで<code>*</code>ワイルドカードを使用できます。上記の例を続けると、このクエリは機能的には<code>emantic_text_field_1</code> 、 <code>semantic_text_field_2</code> 、 <code>text_field_1</code>明示的にクエリすることと同等です。</p>GET linear_retriever_example/_search
{
  "retriever": {
    "linear": {
      "fields": [ "semantic_text_field_*", "*_field_1" ],
      "query": "foo",
      "normalizer": "minmax"
    }
  }
}<p>興味深いことに、 <code>*_field_1</code>パターンは<code>text_field_1</code>と<code>semantic_text_field_1</code>の両方に一致します。これは自動的に処理され、各フィールドが明示的にクエリされたかのようにクエリが実行されます。<code>semantic_text_field_1</code>が両方のパターンに一致することも問題ありません。すべてのフィールド名の一致は、クエリの実行前に重複が排除されます。</p><p>ワイルドカードはさまざまな方法で使用できます。</p><ul><li><p>プレフィックス一致（例： <code>*_text_field</code> ）</p></li><li><p>インラインマッチング（例： <code>semantic_*_field</code> ）</p></li><li><p>サフィックス一致（例： <code>semantic_text_field_*</code> ）</p></li></ul><p><code>*_text_field_*</code>のように、複数のワイルドカードを使用して上記の組み合わせを適用することもできます。</p><h3>デフォルトのクエリフィールド</h3><p>マルチフィールド クエリ形式を使用すると、何も知らないインデックスをクエリすることもできます。<code>fields</code>パラメータを省略すると、 <a href="https://www.elastic.co/docs/reference/elasticsearch/index-settings/index-modules">index.query.default_field インデックス設定</a>で指定されたすべてのフィールドがクエリされます。</p>GET linear_retriever_example/_search
{
  "retriever": {
    "linear": {
      "query": "foo",
      "normalizer": "minmax"
    }
  }
}<p>デフォルトでは、 <code>index.query.default_field</code>は<code>*</code>に設定されています。このワイルドカードは、用語クエリをサポートするインデックス内のすべてのフィールド タイプ (ほとんど) に解決されます。例外は次のとおりです:</p><ul><li><p><code>dense_vector</code> フィールド</p></li><li><p><code>rank_vector</code> フィールド</p></li><li><p>ジオメトリフィールド: <code>geo_point</code> 、 <code>shape</code></p></li></ul><p>この機能は、サードパーティが提供するインデックスに対してハイブリッド検索クエリを実行する場合に特に便利です。マルチフィールド クエリ形式を使用すると、適切なクエリを簡単な方法で実行できます。<code>fields</code>パラメータを除外するだけで、該当するすべてのフィールドが照会されます。</p><h2>まとめ</h2><p>スコア範囲の問題により、特にクエリ対象のインデックスや使用中の推論エンドポイントに関する情報が限られている場合、効果的なハイブリッド検索の実装が困難になる可能性があります。リニア リトリーバーと RRF リトリーバーのマルチフィールド クエリ形式では、自動化されたクエリ グループ化ベースのハイブリッド検索アプローチをシンプルで使いやすい API にパッケージ化することで、この煩わしさを軽減します。フィールドごとのブースト、ワイルドカード解決、デフォルトのクエリ フィールドなどの追加機能により、機能が拡張され、多くのユース ケースをカバーできます。</p><h2>今すぐマルチフィールドクエリ形式をお試しください</h2><p>無料トライアル では、完全に管理された Elasticsearch<a href="https://www.elastic.co/cloud/serverless"> Serverless</a> プロジェクトで、マルチフィールド<a href="https://www.elastic.co/docs/deploy-manage/deploy/elastic-cloud/create-serverless-project"> クエリ形式を使用した線形リトリーバーと RRF</a> リトリーバーを試すことができます。8.19 および 9.1 以降のスタック バージョンでも利用できます。</p><p>1 つのコマンドでローカル環境で数分以内に開始できます。</p>curl -fsSL https://elastic.co/start-local | sh<p></p>]]></content:encoded>
    <link>https://www.elastic.co/search-labs/blog/hybrid-search-multi-field-query-retrievers-elasticsearch</link>
    <guid isPermaLink="true">https://www.elastic.co/search-labs/blog/hybrid-search-multi-field-query-retrievers-elasticsearch</guid>
    <category><![CDATA[ハイブリッド検索]]></category>
    <category><![CDATA[関連性]]></category>
    <dc:creator><![CDATA[Mike Pellegrini]]></dc:creator>
    <enclosure url="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt89e066372c549595/6a17f17c3e9e457c38ba1583/4494f98ae3958bbdbc6171df9677fc4d65ec5640-1536x1024.png" length="0" type="image/png"/>
    <pubDate>Thu, 27 Nov 2025 00:00:00 GMT</pubDate>
  </item>
  </channel>
</rss>