スパースベクトルクエリ

スパースベクトルクエリは、学習されたスパース検索モデルによって構築されたスパースベクトルからなるクエリを実行します。これは、次の2つの戦略のいずれかを使用して実現できます:

  • 自然言語処理モデルを使用して、クエリテキストをトークン-ウェイトペアのリストに変換する
  • 事前計算されたトークン-ウェイトペアをクエリベクトルとして送信する

これらのトークン-ウェイトペアは、スパースベクトルに対するクエリに使用されます。クエリ時には、トークンを作成するために使用されたのと同じ推論モデルを使用してクエリベクトルが計算されます。クエリを実行する際、これらのクエリベクトルはそれぞれのウェイトと共にOR演算され、スコアリングは実質的に保存された次元とクエリ次元の間のドット積計算となります。

例えば、保存されたベクトル{"feature_0": 0.12, "feature_1": 1.2, "feature_2": 3.0}とクエリベクトル{"feature_0": 2.5, "feature_2": 0.2}は、ドキュメント_score = 0.12*2.5 + 3.0*0.2 = 0.9にスコアを付けます。

自然言語処理モデルを使用した例のリクエスト

Python

  1. resp = client.search(
  2. query={
  3. "sparse_vector": {
  4. "field": "ml.tokens",
  5. "inference_id": "the inference ID to produce the token weights",
  6. "query": "the query string"
  7. }
  8. },
  9. )
  10. print(resp)

Js

  1. const response = await client.search({
  2. query: {
  3. sparse_vector: {
  4. field: "ml.tokens",
  5. inference_id: "the inference ID to produce the token weights",
  6. query: "the query string",
  7. },
  8. },
  9. });
  10. console.log(response);

コンソール

  1. GET _search
  2. {
  3. "query":{
  4. "sparse_vector": {
  5. "field": "ml.tokens",
  6. "inference_id": "the inference ID to produce the token weights",
  7. "query": "the query string"
  8. }
  9. }
  10. }

事前計算されたベクトルを使用した例のリクエスト

Python

  1. resp = client.search(
  2. query={
  3. "sparse_vector": {
  4. "field": "ml.tokens",
  5. "query_vector": {
  6. "token1": 0.5,
  7. "token2": 0.3,
  8. "token3": 0.2
  9. }
  10. }
  11. },
  12. )
  13. print(resp)

Js

  1. const response = await client.search({
  2. query: {
  3. sparse_vector: {
  4. field: "ml.tokens",
  5. query_vector: {
  6. token1: 0.5,
  7. token2: 0.3,
  8. token3: 0.2,
  9. },
  10. },
  11. },
  12. });
  13. console.log(response);

コンソール

  1. GET _search
  2. {
  3. "query":{
  4. "sparse_vector": {
  5. "field": "ml.tokens",
  6. "query_vector": { "token1": 0.5, "token2": 0.3, "token3": 0.2 }
  7. }
  8. }
  9. }

スパースベクトルのトップレベルパラメータ

  • field
  • (必須、文字列) 検索対象のトークン-ウェイトペアを含むフィールドの名前。
  • inference_id
  • (オプション、文字列) クエリテキストをトークン-ウェイトペアに変換するために使用するinference ID。これは、入力テキストからトークンを作成するために使用されたのと同じ推論IDでなければなりません。inference_idquery_vectorのいずれか一方のみが許可されます。inference_idが指定されている場合、queryも指定されなければなりません。
  • query
  • (オプション、文字列) 検索に使用したいクエリテキスト。inference_idが指定されている場合、queryも指定されなければなりません。query_vectorが指定されている場合、queryは指定されてはなりません。
  • query_vector
  • (オプション、辞書) 検索するための事前計算されたクエリベクトルを表すトークン-ウェイトペアの辞書。このクエリベクトルを使用して検索すると、追加の推論をバイパスします。inference_idquery_vectorのいずれか一方のみが許可されます。
  • prune
  • (オプション、ブール値) [プレビュー] この機能は技術プレビュー中であり、将来のリリースで変更または削除される可能性があります。Elasticは問題を修正するために取り組みますが、技術プレビューの機能は公式GA機能のサポートSLAの対象ではありません。 クエリのパフォーマンスを向上させるために、重要でないトークンを省略するためにプルーニングを実行するかどうか。pruneがtrueであるがpruning_configが指定されていない場合、プルーニングは行われますが、デフォルト値が使用されます。デフォルト:false。
  • pruning_config
  • (オプション、オブジェクト) [プレビュー] この機能は技術プレビュー中であり、将来のリリースで変更または削除される可能性があります。Elasticは問題を修正するために取り組みますが、技術プレビューの機能は公式GA機能のサポートSLAの対象ではありません。 オプションのプルーニング設定。これが有効な場合、クエリのパフォーマンスを向上させるために重要でないトークンを省略します。これは、prunetrueに設定されている場合のみ使用されます。prunetrueに設定されているがpruning_configが指定されていない場合、デフォルト値が使用されます。
    1. - `````tokens_freq_ratio_threshold
    • (オプション、整数) [プレビュー] この機能は技術プレビュー中であり、将来のリリースで変更または削除される可能性があります。Elasticは問題を修正するために取り組みますが、技術プレビューの機能は公式GA機能のサポートSLAの対象ではありません。 指定されたフィールド内のすべてのトークンの平均頻度のtokens_freq_ratio_threshold倍を超える頻度を持つトークンは外れ値と見なされ、プルーニングされます。この値は1から100の間でなければなりません。デフォルト:5
    • tokens_weight_threshold
    • (オプション、浮動小数点数) [プレビュー] この機能は技術プレビュー中であり、将来のリリースで変更または削除される可能性があります。Elasticは問題を修正するために取り組みますが、技術プレビューの機能は公式GA機能のサポートSLAの対象ではありません。 tokens_weight_threshold未満の重みを持つトークンは重要でないと見なされ、プルーニングされます。この値は0から1の間でなければなりません。デフォルト:0.4
    • only_score_pruned_tokens
    • (オプション、ブール値) [プレビュー] この機能は技術プレビュー中であり、将来のリリースで変更または削除される可能性があります。Elasticは問題を修正するために取り組みますが、技術プレビューの機能は公式GA機能のサポートSLAの対象ではありません。 trueの場合、スコアリングにプルーニングされたトークンのみを入力し、プルーニングされていないトークンを破棄します。メインクエリにはfalseに設定することを強く推奨しますが、リスコアクエリにはtrueに設定してより関連性の高い結果を得ることができます。デフォルト:false
      tokens_freq_ratio_thresholdtokens_weight_thresholdのデフォルト値は、最も最適な結果を提供するELSERv2を使用したテストに基づいて選択されました。

ELSERクエリの例

以下は、ELSERモデルを参照して意味検索を実行するsparse_vectorクエリの例です。ELSERを使用して意味検索を実行する方法の詳細な説明については、このチュートリアルを参照してください。

Python

  1. resp = client.search(
  2. index="my-index",
  3. query={
  4. "sparse_vector": {
  5. "field": "ml.tokens",
  6. "inference_id": "my-elser-model",
  7. "query": "How is the weather in Jamaica?"
  8. }
  9. },
  10. )
  11. print(resp)

Js

  1. const response = await client.search({
  2. index: "my-index",
  3. query: {
  4. sparse_vector: {
  5. field: "ml.tokens",
  6. inference_id: "my-elser-model",
  7. query: "How is the weather in Jamaica?",
  8. },
  9. },
  10. });
  11. console.log(response);

コンソール

  1. GET my-index/_search
  2. {
  3. "query":{
  4. "sparse_vector": {
  5. "field": "ml.tokens",
  6. "inference_id": "my-elser-model",
  7. "query": "How is the weather in Jamaica?"
  8. }
  9. }
  10. }

複数のsparse_vectorクエリは互いにまたは他のクエリタイプと組み合わせることができます。これは、ブールクエリ句でラップし、線形ブースティングを使用することで実現できます:

Python

  1. resp = client.search(
  2. index="my-index",
  3. query={
  4. "bool": {
  5. "should": [
  6. {
  7. "sparse_vector": {
  8. "field": "ml.inference.title_expanded.predicted_value",
  9. "inference_id": "my-elser-model",
  10. "query": "How is the weather in Jamaica?",
  11. "boost": 1
  12. }
  13. },
  14. {
  15. "sparse_vector": {
  16. "field": "ml.inference.description_expanded.predicted_value",
  17. "inference_id": "my-elser-model",
  18. "query": "How is the weather in Jamaica?",
  19. "boost": 1
  20. }
  21. },
  22. {
  23. "multi_match": {
  24. "query": "How is the weather in Jamaica?",
  25. "fields": [
  26. "title",
  27. "description"
  28. ],
  29. "boost": 4
  30. }
  31. }
  32. ]
  33. }
  34. },
  35. )
  36. print(resp)

Js

  1. const response = await client.search({
  2. index: "my-index",
  3. query: {
  4. bool: {
  5. should: [
  6. {
  7. sparse_vector: {
  8. field: "ml.inference.title_expanded.predicted_value",
  9. inference_id: "my-elser-model",
  10. query: "How is the weather in Jamaica?",
  11. boost: 1,
  12. },
  13. },
  14. {
  15. sparse_vector: {
  16. field: "ml.inference.description_expanded.predicted_value",
  17. inference_id: "my-elser-model",
  18. query: "How is the weather in Jamaica?",
  19. boost: 1,
  20. },
  21. },
  22. {
  23. multi_match: {
  24. query: "How is the weather in Jamaica?",
  25. fields: ["title", "description"],
  26. boost: 4,
  27. },
  28. },
  29. ],
  30. },
  31. },
  32. });
  33. console.log(response);

コンソール

  1. GET my-index/_search
  2. {
  3. "query": {
  4. "bool": {
  5. "should": [
  6. {
  7. "sparse_vector": {
  8. "field": "ml.inference.title_expanded.predicted_value",
  9. "inference_id": "my-elser-model",
  10. "query": "How is the weather in Jamaica?",
  11. "boost": 1
  12. }
  13. },
  14. {
  15. "sparse_vector": {
  16. "field": "ml.inference.description_expanded.predicted_value",
  17. "inference_id": "my-elser-model",
  18. "query": "How is the weather in Jamaica?",
  19. "boost": 1
  20. }
  21. },
  22. {
  23. "multi_match": {
  24. "query": "How is the weather in Jamaica?",
  25. "fields": [
  26. "title",
  27. "description"
  28. ],
  29. "boost": 4
  30. }
  31. }
  32. ]
  33. }
  34. }
  35. }

これは、逆順位融合 (RRF)を使用して、複数のstandardリトリーバーを持つrrfリトリーバーを通じて実現することもできます。

Python

  1. resp = client.search(
  2. index="my-index",
  3. retriever={
  4. "rrf": {
  5. "retrievers": [
  6. {
  7. "standard": {
  8. "query": {
  9. "multi_match": {
  10. "query": "How is the weather in Jamaica?",
  11. "fields": [
  12. "title",
  13. "description"
  14. ]
  15. }
  16. }
  17. }
  18. },
  19. {
  20. "standard": {
  21. "query": {
  22. "sparse_vector": {
  23. "field": "ml.inference.title_expanded.predicted_value",
  24. "inference_id": "my-elser-model",
  25. "query": "How is the weather in Jamaica?",
  26. "boost": 1
  27. }
  28. }
  29. }
  30. },
  31. {
  32. "standard": {
  33. "query": {
  34. "sparse_vector": {
  35. "field": "ml.inference.description_expanded.predicted_value",
  36. "inference_id": "my-elser-model",
  37. "query": "How is the weather in Jamaica?",
  38. "boost": 1
  39. }
  40. }
  41. }
  42. }
  43. ],
  44. "window_size": 10,
  45. "rank_constant": 20
  46. }
  47. },
  48. )
  49. print(resp)

Js

  1. const response = await client.search({
  2. index: "my-index",
  3. retriever: {
  4. rrf: {
  5. retrievers: [
  6. {
  7. standard: {
  8. query: {
  9. multi_match: {
  10. query: "How is the weather in Jamaica?",
  11. fields: ["title", "description"],
  12. },
  13. },
  14. },
  15. },
  16. {
  17. standard: {
  18. query: {
  19. sparse_vector: {
  20. field: "ml.inference.title_expanded.predicted_value",
  21. inference_id: "my-elser-model",
  22. query: "How is the weather in Jamaica?",
  23. boost: 1,
  24. },
  25. },
  26. },
  27. },
  28. {
  29. standard: {
  30. query: {
  31. sparse_vector: {
  32. field: "ml.inference.description_expanded.predicted_value",
  33. inference_id: "my-elser-model",
  34. query: "How is the weather in Jamaica?",
  35. boost: 1,
  36. },
  37. },
  38. },
  39. },
  40. ],
  41. window_size: 10,
  42. rank_constant: 20,
  43. },
  44. },
  45. });
  46. console.log(response);

コンソール

  1. GET my-index/_search
  2. {
  3. "retriever": {
  4. "rrf": {
  5. "retrievers": [
  6. {
  7. "standard": {
  8. "query": {
  9. "multi_match": {
  10. "query": "How is the weather in Jamaica?",
  11. "fields": [
  12. "title",
  13. "description"
  14. ]
  15. }
  16. }
  17. }
  18. },
  19. {
  20. "standard": {
  21. "query": {
  22. "sparse_vector": {
  23. "field": "ml.inference.title_expanded.predicted_value",
  24. "inference_id": "my-elser-model",
  25. "query": "How is the weather in Jamaica?",
  26. "boost": 1
  27. }
  28. }
  29. }
  30. },
  31. {
  32. "standard": {
  33. "query": {
  34. "sparse_vector": {
  35. "field": "ml.inference.description_expanded.predicted_value",
  36. "inference_id": "my-elser-model",
  37. "query": "How is the weather in Jamaica?",
  38. "boost": 1
  39. }
  40. }
  41. }
  42. }
  43. ],
  44. "window_size": 10,
  45. "rank_constant": 20
  46. }
  47. }
  48. }

プルーニング設定とリスコアを伴うELSERクエリの例

以下は、sparse_vectorクエリにプルーニング設定を追加した上記の例の拡張です。このプルーニング設定は、クエリのパフォーマンスを向上させるためにプルーニングする重要でないトークンを特定します。

トークンプルーニングはシャードレベルで行われます。これにより、シャード全体で同じトークンが重要でないとラベル付けされるはずですが、各シャードの構成に基づいて保証されるものではありません。したがって、マルチシャードインデックスでsparse_vectorpruning_configと共に実行している場合、元々クエリからプルーニングされたトークンを使用してリスコアフィルタリングされた検索結果機能を追加することを強くお勧めします。これにより、プルーニングされたトークンのシャードレベルの不整合を軽減し、全体的な関連性を向上させることができます。

Python

  1. resp = client.search(
  2. index="my-index",
  3. query={
  4. "sparse_vector": {
  5. "field": "ml.tokens",
  6. "inference_id": "my-elser-model",
  7. "query": "How is the weather in Jamaica?",
  8. "prune": True,
  9. "pruning_config": {
  10. "tokens_freq_ratio_threshold": 5,
  11. "tokens_weight_threshold": 0.4,
  12. "only_score_pruned_tokens": False
  13. }
  14. }
  15. },
  16. rescore={
  17. "window_size": 100,
  18. "query": {
  19. "rescore_query": {
  20. "sparse_vector": {
  21. "field": "ml.tokens",
  22. "inference_id": "my-elser-model",
  23. "query": "How is the weather in Jamaica?",
  24. "prune": True,
  25. "pruning_config": {
  26. "tokens_freq_ratio_threshold": 5,
  27. "tokens_weight_threshold": 0.4,
  28. "only_score_pruned_tokens": True
  29. }
  30. }
  31. }
  32. }
  33. },
  34. )
  35. print(resp)

Js

  1. const response = await client.search({
  2. index: "my-index",
  3. query: {
  4. sparse_vector: {
  5. field: "ml.tokens",
  6. inference_id: "my-elser-model",
  7. query: "How is the weather in Jamaica?",
  8. prune: true,
  9. pruning_config: {
  10. tokens_freq_ratio_threshold: 5,
  11. tokens_weight_threshold: 0.4,
  12. only_score_pruned_tokens: false,
  13. },
  14. },
  15. },
  16. rescore: {
  17. window_size: 100,
  18. query: {
  19. rescore_query: {
  20. sparse_vector: {
  21. field: "ml.tokens",
  22. inference_id: "my-elser-model",
  23. query: "How is the weather in Jamaica?",
  24. prune: true,
  25. pruning_config: {
  26. tokens_freq_ratio_threshold: 5,
  27. tokens_weight_threshold: 0.4,
  28. only_score_pruned_tokens: true,
  29. },
  30. },
  31. },
  32. },
  33. },
  34. });
  35. console.log(response);

コンソール

  1. GET my-index/_search
  2. {
  3. "query":{
  4. "sparse_vector":{
  5. "field": "ml.tokens",
  6. "inference_id": "my-elser-model",
  7. "query":"How is the weather in Jamaica?",
  8. "prune": true,
  9. "pruning_config": {
  10. "tokens_freq_ratio_threshold": 5,
  11. "tokens_weight_threshold": 0.4,
  12. "only_score_pruned_tokens": false
  13. }
  14. }
  15. },
  16. "rescore": {
  17. "window_size": 100,
  18. "query": {
  19. "rescore_query": {
  20. "sparse_vector": {
  21. "field": "ml.tokens",
  22. "inference_id": "my-elser-model",
  23. "query": "How is the weather in Jamaica?",
  24. "prune": true,
  25. "pruning_config": {
  26. "tokens_freq_ratio_threshold": 5,
  27. "tokens_weight_threshold": 0.4,
  28. "only_score_pruned_tokens": true
  29. }
  30. }
  31. }
  32. }
  33. }
  34. }

クロスクラスター検索を実行する際、推論はローカルクラスターで実行されます。