テキスト拡張クエリ

8.15.0で非推奨。

このクエリは、スパースベクトルに置き換えられました。

テキスト拡張クエリは、自然言語処理モデルを使用して、クエリテキストをトークン-ウェイトペアのリストに変換し、それをスパースベクトルまたはランクフィーチャーフィールドに対するクエリに使用します。

例リクエスト

Python

  1. resp = client.search(
  2. query={
  3. "text_expansion": {
  4. "<sparse_vector_field>": {
  5. "model_id": "the model to produce the token weights",
  6. "model_text": "the query string"
  7. }
  8. }
  9. },
  10. )
  11. print(resp)

Ruby

  1. response = client.search(
  2. body: {
  3. query: {
  4. text_expansion: {
  5. "<sparse_vector_field>": {
  6. model_id: 'the model to produce the token weights',
  7. model_text: 'the query string'
  8. }
  9. }
  10. }
  11. }
  12. )
  13. puts response

Js

  1. const response = await client.search({
  2. query: {
  3. text_expansion: {
  4. "<sparse_vector_field>": {
  5. model_id: "the model to produce the token weights",
  6. model_text: "the query string",
  7. },
  8. },
  9. },
  10. });
  11. console.log(response);

コンソール

  1. GET _search
  2. {
  3. "query":{
  4. "text_expansion":{
  5. "<sparse_vector_field>":{
  6. "model_id":"the model to produce the token weights",
  7. "model_text":"the query string"
  8. }
  9. }
  10. }
  11. }

テキスト拡張のトップレベルパラメータ

  • <sparse_vector_field>
  • (必須、オブジェクト) 入力テキストに基づいてNLPモデルが作成したトークン-ウェイトペアを含むフィールドの名前。

<sparse_vector_field>のトップレベルパラメータ

  • model_id
  • (必須、文字列) クエリテキストをトークン-ウェイトペアに変換するために使用するモデルのID。これは、入力テキストからトークンを作成するために使用されたモデルIDと同じでなければなりません。
  • model_text
  • (必須、文字列) 検索に使用したいクエリテキスト。
  • pruning_config
  • (オプション、オブジェクト) [プレビュー] この機能は技術プレビュー中であり、将来のリリースで変更または削除される可能性があります。Elasticは問題を修正するために作業しますが、技術プレビューの機能は公式GA機能のサポートSLAの対象ではありません。 オプションのプルーニング設定。これが有効な場合、クエリのパフォーマンスを向上させるために、重要でないトークンをクエリから省略します。デフォルト: 無効。
    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のデフォルト値は、最も最適な結果を提供するELSERを使用したテストに基づいて選択されました。

ELSERクエリの例

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

Python

  1. resp = client.search(
  2. index="my-index",
  3. query={
  4. "text_expansion": {
  5. "ml.tokens": {
  6. "model_id": ".elser_model_2",
  7. "model_text": "How is the weather in Jamaica?"
  8. }
  9. }
  10. },
  11. )
  12. print(resp)

Ruby

  1. response = client.search(
  2. index: 'my-index',
  3. body: {
  4. query: {
  5. text_expansion: {
  6. 'ml.tokens' => {
  7. model_id: '.elser_model_2',
  8. model_text: 'How is the weather in Jamaica?'
  9. }
  10. }
  11. }
  12. }
  13. )
  14. puts response

Js

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

コンソール

  1. GET my-index/_search
  2. {
  3. "query":{
  4. "text_expansion":{
  5. "ml.tokens":{
  6. "model_id":".elser_model_2",
  7. "model_text":"How is the weather in Jamaica?"
  8. }
  9. }
  10. }
  11. }

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

Python

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

Ruby

  1. response = client.search(
  2. index: 'my-index',
  3. body: {
  4. query: {
  5. bool: {
  6. should: [
  7. {
  8. text_expansion: {
  9. 'ml.inference.title_expanded.predicted_value' => {
  10. model_id: '.elser_model_2',
  11. model_text: 'How is the weather in Jamaica?',
  12. boost: 1
  13. }
  14. }
  15. },
  16. {
  17. text_expansion: {
  18. 'ml.inference.description_expanded.predicted_value' => {
  19. model_id: '.elser_model_2',
  20. model_text: 'How is the weather in Jamaica?',
  21. boost: 1
  22. }
  23. }
  24. },
  25. {
  26. multi_match: {
  27. query: 'How is the weather in Jamaica?',
  28. fields: [
  29. 'title',
  30. 'description'
  31. ],
  32. boost: 4
  33. }
  34. }
  35. ]
  36. }
  37. }
  38. }
  39. )
  40. puts response

Js

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

コンソール

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

これは、逆順位融合 (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. "text_expansion": {
  23. "ml.inference.title_expanded.predicted_value": {
  24. "model_id": ".elser_model_2",
  25. "model_text": "How is the weather in Jamaica?"
  26. }
  27. }
  28. }
  29. }
  30. },
  31. {
  32. "standard": {
  33. "query": {
  34. "text_expansion": {
  35. "ml.inference.description_expanded.predicted_value": {
  36. "model_id": ".elser_model_2",
  37. "model_text": "How is the weather in Jamaica?"
  38. }
  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. text_expansion: {
  20. "ml.inference.title_expanded.predicted_value": {
  21. model_id: ".elser_model_2",
  22. model_text: "How is the weather in Jamaica?",
  23. },
  24. },
  25. },
  26. },
  27. },
  28. {
  29. standard: {
  30. query: {
  31. text_expansion: {
  32. "ml.inference.description_expanded.predicted_value": {
  33. model_id: ".elser_model_2",
  34. model_text: "How is the weather in Jamaica?",
  35. },
  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. "text_expansion": {
  23. "ml.inference.title_expanded.predicted_value": {
  24. "model_id": ".elser_model_2",
  25. "model_text": "How is the weather in Jamaica?"
  26. }
  27. }
  28. }
  29. }
  30. },
  31. {
  32. "standard": {
  33. "query": {
  34. "text_expansion": {
  35. "ml.inference.description_expanded.predicted_value": {
  36. "model_id": ".elser_model_2",
  37. "model_text": "How is the weather in Jamaica?"
  38. }
  39. }
  40. }
  41. }
  42. }
  43. ],
  44. "window_size": 10,
  45. "rank_constant": 20
  46. }
  47. }
  48. }

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

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

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

Python

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

Ruby

  1. response = client.search(
  2. index: 'my-index',
  3. body: {
  4. query: {
  5. text_expansion: {
  6. 'ml.tokens' => {
  7. model_id: '.elser_model_2',
  8. model_text: 'How is the weather in Jamaica?',
  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. },
  17. rescore: {
  18. window_size: 100,
  19. query: {
  20. rescore_query: {
  21. text_expansion: {
  22. 'ml.tokens' => {
  23. model_id: '.elser_model_2',
  24. model_text: 'How is the weather in Jamaica?',
  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. }
  36. )
  37. puts response

Js

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

コンソール

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

データによっては、テキスト拡張クエリはtrack_total_hits: falseでより高速になる場合があります。