🔍

[翻訳] pagination_depth パラメータを使用したハイブリッドクエリでのページネーションのナビゲーション

に公開

本投稿は OpenSearch Project Blog "Navigating pagination in hybrid queries with the pagination_depth parameter" の日本語訳です。


OpenSearch 2.10 では、セマンティック検索の関連性を向上させるための人気の選択肢となっているハイブリッドクエリが導入されました。レキシカル検索とセマンティック検索を組み合わせることで、ハイブリッドクエリは e コマース、ドキュメント検索、ログ分析、データ探索など、さまざまなアプリケーションにおいて、どちらの方法単独よりも優れた結果を提供します。以前のブログ投稿では、この機能を紹介し、品質とパフォーマンスの結果を示しました。

OpenSearch は、ポストフィルター、集約、クエリの並列化、explain パラメータ、ソートなどの機能により、ハイブリッドクエリ機能を継続的に強化しています。この勢いに乗って、OpenSearch 2.19 では、新しい pagination_depth パラメータによるページネーションサポートが導入されました。従来の from パラメータと size パラメータと組み合わせて使用することで、ハイブリッドクエリの結果セットを効率的にナビゲートできるようになります。例えば、数千の検索結果を 1 ページずつページネーションできるようになりました。

このブログ投稿では、ページネーションと pagination_depth パラメータについて説明します。pagination_depth がハイブリッドクエリに必要な理由を探り、この機能の使用方法を示し、ベンチマーク結果を共有します。

ページネーションの理解

OpenSearch はページネーションを使用して、大きな結果セットを管理しやすいページに分割します。各ページには、検索リクエストの size パラメータで指定された数の検索結果が含まれます。OpenSearch は 4 つのページネーション技術をサポートしています

  • from パラメータと size パラメータ
  • scroll search
  • search_after パラメータ
  • Point in Time と search_after の組み合わせ

これらの技術の詳細については、OpenSearch ドキュメントを参照してください。

このブログ投稿では、ハイブリッドクエリにおける新しい pagination_depth パラメータと from パラメータおよび size パラメータの使用に焦点を当てています。

pagination_depth の仕組み

pagination_depth パラメータは、各サブクエリについて各シャードから取得する検索結果の最大数を指定します。これにより、各サブクエリでハイブリッド化する結果の数を正確に制御できます。

次の図は、3 つのシャードを持つインデックスを示しています。例のハイブリッドクエリ検索リクエストには、2 つのサブクエリ (match クエリと k-NN クエリ) が含まれており、pagination_depth = 20、size = 10、from = 5 となっています。

この例の仕組みは次のとおりです:

  1. pagination_depth が 20 に設定されているため、各シャードは match クエリと k-NN クエリの両方について最大 20 件の結果を取得します (この例では、各シャードにクエリごとに少なくとも 20 件の結果が含まれていると仮定しています)。
  2. コーディネーターノードは合計 120 件の結果 (match クエリ用に 60 件、k-NN クエリ用に 60 件) を受け取り、正規化やスコアの組み合わせなどのハイブリッド検索技術を使用してそれらを処理します。
  3. ハイブリッド検索技術を適用する際、両方のサブクエリに表示される重複結果は単一の結果にマージされます。
  4. 最終結果は、上位 10 件の結果 (size = 10 のため) に従ってトリミングされ、5 番目のエントリ (from = 5 のため) から始まります。

このプロセスにより、ハイブリッド検索は複数のサブクエリからの結果を効率的にマージしてランク付けし、ページネーションの制約を尊重します。

pagination_depth が重要な理由

従来のクエリ (match や term など) は、各シャードから取得する検索結果の最大数を決定するために、単純な from + size の式を使用します。しかし、同じ式をハイブリッド検索に適用すると、結果の正確性、つまり「グランドトゥルース」に影響する課題が生じます。グランドトゥルースとは、推論ではなく直接観察から得られる情報を指します。実際には、合理的な条件下での最良のテストまたはベンチマークを表します。これは、顧客フィードバック、人間によるラベル付け、または分類が不完全な場合でも、利用可能な最も信頼性の高いテスト方法を通じて、データの正確性を検証するための基盤となります。

例として、次のパラメータを持つハイブリッドクエリ検索リクエストを考えてみましょう

  • from = 0
  • size = 3

このリクエストには、hybrid 句の下に match クエリと k-NN クエリの 2 つのサブクエリが含まれています。正規化プロセッサは、次の図に示すように、match クエリ (0.7) に k-NN クエリ (0.3) よりも大きな重みを割り当てるように構成されています。

from + size 式がグラウンドトゥルースに与える影響

from または size の値を変更すると、シャードから各サブクエリに対して取得される結果の数が増加します。しかし、これらの新しい結果は単に最後のページに追加されるわけではありません。ランク付けされたリストの前の方に表示され、ページネーションしようとしているグラウンドトゥルースを変更する可能性があります。主に、以下の 2 つのシナリオで発生します

  1. 高い重みを持つサブクエリの効果

    • 高い重みを持つサブクエリからの新しい結果は、スコアの組み合わせ後に上位にランク付けされる可能性があります。
    • その結果、これらの新しいエントリは、最後ではなく、最終結果セットの前の方 (最初の数ページまたは途中のどこか) に表示され、予想されるページネーション順序を乱す可能性があります。

    例えば、size を 4 に増やすと予期しない結果が生じます。新しいクエリ 1 の結果 (ドキュメント ID 14) は、次の図に示すように、正規化中のクエリ 1 の高い重みのために、最後ではなく 4 番目のドキュメントとして表示されます。

  1. 重複結果の効果
    • 新しく取得された結果は重複になる可能性があります。つまり、両方のサブクエリ結果に存在する可能性があります。
    • スコア組み合わせプロセスの後、重複エントリの組み合わせスコアが増加し、より関連性が高くなります。
    • サブクエリの重みが等しい場合、重複結果は予想よりも高くランク付けされ、検索結果の上位に表示されます。

次の図では、ID が 0 と 12 のドキュメントは、match サブクエリと k-NN サブクエリの両方に表示される重複結果です。重複ドキュメントは通常、重複していないドキュメントよりも高いハイブリッドスコアを受け取るため、結果の上位に表示され、予想されるページネーション順序が乱れます。

グラウンドトゥルースの問題への対処

pagination_depth パラメータは、シャードごとに一貫した結果数を確保することでこれらの問題を解決します。これにより、結果の取得中に from と size への依存がなくなり、毎回同じ検索結果セットが返されることが保証されます。from パラメータと size パラメータは、ハイブリッド技術の適用後に結果をトリミングし、各ページに表示する結果の数を決定するために適用されます。

重要なポイント

次の重要なポイントに注意してください

  • 一貫した結果を維持するために、ページ間をナビゲートする際は pagination_depth を一定に保ちます。
  • ページネーション中に pagination_depth を変更すると、一貫性のない結果になります。

前の例では、pagination_depth = 5 を設定することでグラウンドトゥルースの問題に対処しています。match クエリと k-NN クエリの両方が、コーディネーターノードに各シャードから最大 5 件の結果を返し、サブクエリ結果にハイブリッド技術を適用できるようにします。次の図に示すように、from パラメータと size パラメータがハイブリッド検索結果のトリミング方法を決定します。

ハイブリッドクエリでのページネーションの使用方法

ページ間をナビゲートするには、ハイブリッドクエリ句で pagination_depth パラメータを指定します。次の例では、pagination_depth = 10、from = 0、size = 5 を設定しています

GET /my-nlp-index/_search?search_pipeline=nlp-search-pipeline
{
  "from": 0,
  "size": 5,
  "query": {
    "hybrid": {
      "pagination_depth": 10,
      "queries": [
        {
          "term": {
            "category": "permission"
          }
        },
        {
          "bool": {
            "should": [
              {
                "term": {
                  "category": "editor"
                }
              },
              {
                "term": {
                  "category": "statement"
                }
              }
            ]
          }
        }
      ]
    }
  }
}

この例の詳細な説明については、ハイブリッドクエリ結果のページネーションを参照してください。

パフォーマンスへの影響

異なる pagination_depth 値が CPU 使用率とレイテンシーにどのように影響するかを評価するためにベンチマークを実施しました。テストでは opensearch-benchmark-workloads から noaa_semantic_search データセットを使用しました。

ベンチマーク構成

6 つの構成をテストしました。すべて 2 ページ目の結果 (from = 100、size = 100) を返し、pagination_depth 値を変えています:

  • 50
  • 100
  • 500
  • 1,000
  • 5,000
  • 10,000

テストしたクエリタイプ

2 つのクエリタイプを評価しました:

  1. 3 つのサブクエリ (term、range、date) を含むハイブリッドクエリ
  2. 3 つのサブクエリ (term、range、date) を含むハイブリッドクエリに適用されたメトリック集約

完全なクエリ定義は hybrid_search.json で利用可能です。ベンチマークは hybrid-query-aggs-light 手順を使用して実行されました。

結果

テストでは 1 億 3,400 万ドキュメント (noaa_semantic_search データセットの 4 コピー) を含むインデックスを使用しました。

以下のグラフは、3 つの BM25 サブクエリ (term、range、date) を含むハイブリッドクエリを実行した結果を示しています。

以下のグラフは、3 つの BM25 サブクエリ (term、range、date) を含むハイブリッドクエリにメトリック集約を実行した結果を示しています。

以下のグラフは CPU 使用率の結果を示しています。

パフォーマンスの概要

結果は緩やかで予測可能なパフォーマンスの変化を示しています:

  • レイテンシーや CPU 使用率の大きなスパイクはありません。
  • レイテンシーメトリック (p50、p90、p99、p100) と CPU 使用率は、ページネーション深度の増加に伴って着実に増加します。

pagination_depth 使用のベストプラクティス

ベンチマークでは、pagination_depth が 10,000 であっても、2 ページ目を取得する際に大きなパフォーマンスへの影響はありませんでした。ただし、ページネーション深度が増加するにつれて、レイテンシーと CPU 使用率の両方が増加します。パフォーマンスを最適化するには、以下のベストプラクティスを検討してください。

データ分布に基づいてページネーション深度を最適化する

ページネーションの効率は、データがシャード間でどれだけ均等に分散されているかによって異なります。この分布は _cat/shards API を使用して確認できます。ドキュメントがシャード間で均等に分散されている場合、より小さな pagination_depth でもサブクエリごとにより多くのハイブリッド化された検索結果を提供できます。

例えば:

  • pagination_depth = 20、3 つのシャードの場合、サブクエリごとに最大 60 件の結果をハイブリッド化できます。
  • これは、各シャードにサブクエリごとに少なくとも 20 件の結果が含まれていることを前提としています (つまり、データが均等に分散されている)。
  • サブクエリに重複エントリがない場合、最大 120 件のハイブリッド化された検索結果をページネーションできます。

不均等なデータ分布を管理する

カスタムルーティングにより、シャード間でデータが不均等に分散し、一部のシャードがゼロ結果を返す可能性があり、ハイブリッド化された結果の総数が減少します。

さらに、カスタムルーティングにより、一部のシャードに関連するすべての結果が含まれる場合があります。前の例を続けると、シャードにサブクエリごとに 20 件以上の結果が含まれている場合でも、(pagination_depth に基づいて) 20 件の結果しか返せません。その結果、コーディネーターノードはハイブリッド化のために少ない結果を受け取り、最終的な検索結果サイズが減少します。

推奨事項のまとめ

パフォーマンスを維持しながら高い関連性を確保するために、ハイブリッド検索を最適化するには次の推奨事項に従ってください

  • 深いページネーションを避ける:ハイブリッド検索は、網羅的なページネーションではなく、関連性に最適化されています。深いページネーションが必要な場合は、bool や match クエリなどの従来の検索方法の使用を検討してください。
  • データを均等に分散する:インデックス作成中にシャードのバランスを取り、クエリ効率を向上させ、高い pagination_depth 値の必要性を最小限に抑えます。

制限事項

ページ間をナビゲートする際に次のエラーが表示される場合があります。

Reached end of search results. Increase pagination_depth value to see more results.

重要なポイントで述べたように、一貫した pagination_depth を維持することで安定した結果が保証されますが、固定された結果セットに制限されます。指定した pagination_depth の最後のページに達すると、OpenSearch は検索結果の終わりに達したことを示すエラーを返します。この時点で、指定された pagination_depth の検索結果を使い果たしています。この制限を超える追加の結果を取得するには、pagination_depth を増やす必要があります。これにより、最終結果セットにより多くの結果を含めることで、検索参照が効果的に拡張されます。

まとめ

このブログ投稿では、pagination_depth がページネーションに from パラメータと size パラメータのみを使用する場合に発生するグラウンドトゥルースの問題をどのように解決するかを探りました。また、最終検索結果の上位ページを取得する際に pagination_depth がパフォーマンスにどのように影響するかも調べました。議論したように、より多くのページを取得するためにページネーションを適用すると、計算時間とコストの両方が増加するため、検索パフォーマンスが低下する可能性があります。パフォーマンスの最適化に役立つように、ハイブリッド検索で pagination_depth を使用するためのベストプラクティスを提供しました。

今後、ハイブリッドクエリをさらに柔軟かつ強力にするために、次の機能を追加する予定です:

  • Inner hits
  • Collapse
  • Filters

Discussion