Suggesters

提供されたテキストに基づいて、似たような用語を提案するためにサジェスターを使用します。

Python

  1. resp = client.search(
  2. index="my-index-000001",
  3. query={
  4. "match": {
  5. "message": "tring out Elasticsearch"
  6. }
  7. },
  8. suggest={
  9. "my-suggestion": {
  10. "text": "tring out Elasticsearch",
  11. "term": {
  12. "field": "message"
  13. }
  14. }
  15. },
  16. )
  17. print(resp)

Ruby

  1. response = client.search(
  2. index: 'my-index-000001',
  3. body: {
  4. query: {
  5. match: {
  6. message: 'tring out Elasticsearch'
  7. }
  8. },
  9. suggest: {
  10. "my-suggestion": {
  11. text: 'tring out Elasticsearch',
  12. term: {
  13. field: 'message'
  14. }
  15. }
  16. }
  17. }
  18. )
  19. puts response

Js

  1. const response = await client.search({
  2. index: "my-index-000001",
  3. query: {
  4. match: {
  5. message: "tring out Elasticsearch",
  6. },
  7. },
  8. suggest: {
  9. "my-suggestion": {
  10. text: "tring out Elasticsearch",
  11. term: {
  12. field: "message",
  13. },
  14. },
  15. },
  16. });
  17. console.log(response);

Console

  1. POST my-index-000001/_search
  2. {
  3. "query" : {
  4. "match": {
  5. "message": "tring out Elasticsearch"
  6. }
  7. },
  8. "suggest" : {
  9. "my-suggestion" : {
  10. "text" : "tring out Elasticsearch",
  11. "term" : {
  12. "field" : "message"
  13. }
  14. }
  15. }
  16. }

Request

サジェスト機能は、提供されたテキストに基づいて似たような用語を提案します。サジェストリクエスト部分は、_searchリクエストのクエリ部分と一緒に定義されます。クエリ部分が省略された場合、提案のみが返されます。

Examples

リクエストごとに複数の提案を指定できます。各提案は任意の名前で識別されます。以下の例では、2つの提案が要求されています。my-suggest-1my-suggest-2の両方の提案はtermサジェスターを使用していますが、textは異なります。

Python

  1. resp = client.search(
  2. suggest={
  3. "my-suggest-1": {
  4. "text": "tring out Elasticsearch",
  5. "term": {
  6. "field": "message"
  7. }
  8. },
  9. "my-suggest-2": {
  10. "text": "kmichy",
  11. "term": {
  12. "field": "user.id"
  13. }
  14. }
  15. },
  16. )
  17. print(resp)

Ruby

  1. response = client.search(
  2. body: {
  3. suggest: {
  4. "my-suggest-1": {
  5. text: 'tring out Elasticsearch',
  6. term: {
  7. field: 'message'
  8. }
  9. },
  10. "my-suggest-2": {
  11. text: 'kmichy',
  12. term: {
  13. field: 'user.id'
  14. }
  15. }
  16. }
  17. }
  18. )
  19. puts response

Js

  1. const response = await client.search({
  2. suggest: {
  3. "my-suggest-1": {
  4. text: "tring out Elasticsearch",
  5. term: {
  6. field: "message",
  7. },
  8. },
  9. "my-suggest-2": {
  10. text: "kmichy",
  11. term: {
  12. field: "user.id",
  13. },
  14. },
  15. },
  16. });
  17. console.log(response);

Console

  1. POST _search
  2. {
  3. "suggest": {
  4. "my-suggest-1" : {
  5. "text" : "tring out Elasticsearch",
  6. "term" : {
  7. "field" : "message"
  8. }
  9. },
  10. "my-suggest-2" : {
  11. "text" : "kmichy",
  12. "term" : {
  13. "field" : "user.id"
  14. }
  15. }
  16. }
  17. }

以下のサジェストレスポンスの例には、my-suggest-1my-suggest-2の提案レスポンスが含まれています。各提案部分にはエントリが含まれています。各エントリは実質的にサジェストテキストからのトークンであり、提案エントリテキスト、サジェストテキスト内の元の開始オフセットと長さ、および見つかった場合の任意の数のオプションが含まれています。

Console-Result

  1. {
  2. "_shards": ...
  3. "hits": ...
  4. "took": 2,
  5. "timed_out": false,
  6. "suggest": {
  7. "my-suggest-1": [ {
  8. "text": "tring",
  9. "offset": 0,
  10. "length": 5,
  11. "options": [ {"text": "trying", "score": 0.8, "freq": 1 } ]
  12. }, {
  13. "text": "out",
  14. "offset": 6,
  15. "length": 3,
  16. "options": []
  17. }, {
  18. "text": "elasticsearch",
  19. "offset": 10,
  20. "length": 13,
  21. "options": []
  22. } ],
  23. "my-suggest-2": ...
  24. }
  25. }

各オプション配列には、提案されたテキスト、その文書頻度、および提案エントリテキストに対するスコアを含むオプションオブジェクトが含まれています。スコアの意味は使用されるサジェスターによって異なります。用語サジェスターのスコアは編集距離に基づいています。

Global suggest text

サジェストテキストの繰り返しを避けるために、グローバルテキストを定義することが可能です。以下の例では、サジェストテキストがグローバルに定義され、my-suggest-1my-suggest-2の提案に適用されます。

Php

  1. $params = [
  2. 'body' => [
  3. 'suggest' => [
  4. 'text' => 'tring out Elasticsearch',
  5. 'my-suggest-1' => [
  6. 'term' => [
  7. 'field' => 'message',
  8. ],
  9. ],
  10. 'my-suggest-2' => [
  11. 'term' => [
  12. 'field' => 'user',
  13. ],
  14. ],
  15. ],
  16. ],
  17. ];
  18. $response = $client->search($params);

Python

  1. resp = client.search(
  2. suggest={
  3. "text": "tring out Elasticsearch",
  4. "my-suggest-1": {
  5. "term": {
  6. "field": "message"
  7. }
  8. },
  9. "my-suggest-2": {
  10. "term": {
  11. "field": "user"
  12. }
  13. }
  14. },
  15. )
  16. print(resp)

Ruby

  1. response = client.search(
  2. body: {
  3. suggest: {
  4. text: 'tring out Elasticsearch',
  5. "my-suggest-1": {
  6. term: {
  7. field: 'message'
  8. }
  9. },
  10. "my-suggest-2": {
  11. term: {
  12. field: 'user'
  13. }
  14. }
  15. }
  16. }
  17. )
  18. puts response

Go

  1. res, err := es.Search(
  2. es.Search.WithBody(strings.NewReader(`{
  3. "suggest": {
  4. "text": "tring out Elasticsearch",
  5. "my-suggest-1": {
  6. "term": {
  7. "field": "message"
  8. }
  9. },
  10. "my-suggest-2": {
  11. "term": {
  12. "field": "user"
  13. }
  14. }
  15. }
  16. }`)),
  17. es.Search.WithPretty(),
  18. )
  19. fmt.Println(res, err)

Js

  1. const response = await client.search({
  2. suggest: {
  3. text: "tring out Elasticsearch",
  4. "my-suggest-1": {
  5. term: {
  6. field: "message",
  7. },
  8. },
  9. "my-suggest-2": {
  10. term: {
  11. field: "user",
  12. },
  13. },
  14. },
  15. });
  16. console.log(response);

Console

  1. POST _search
  2. {
  3. "suggest": {
  4. "text" : "tring out Elasticsearch",
  5. "my-suggest-1" : {
  6. "term" : {
  7. "field" : "message"
  8. }
  9. },
  10. "my-suggest-2" : {
  11. "term" : {
  12. "field" : "user"
  13. }
  14. }
  15. }
  16. }

上記の例では、サジェストテキストも提案特有のオプションとして指定できます。提案レベルで指定されたサジェストテキストは、グローバルレベルのサジェストテキストを上書きします。

Term suggester

  1. #### Common suggest options:
  2. | | |
  3. | --- | --- |
  4. | `````text````` | サジェストテキスト。サジェストテキストは、グローバルまたは提案ごとに設定する必要がある必須オプションです。 |
  5. | `````field````` | 候補提案を取得するフィールド。これはグローバルまたは提案ごとに設定する必要がある必須オプションです。 |
  6. | `````analyzer````` | サジェストテキストを分析するためのアナライザー。デフォルトはサジェストフィールドの検索アナライザーです。 |
  7. | `````size````` | サジェストテキストトークンごとに返される最大修正数。 |
  8. | `````sort````` | サジェストテキスト用語ごとに提案がどのようにソートされるべきかを定義します。2つの可能な値:<br>- `````score`````: スコアで最初にソートし、次に文書頻度、最後に用語自体をソートします。<br>- `````frequency`````: 文書頻度で最初にソートし、次に類似性スコア、最後に用語自体をソートします。 |
  9. | `````suggest_mode````` | サジェストモードは、どの提案が含まれるか、またはどのサジェストテキスト用語に対して提案が行われるべきかを制御します。指定できる3つの可能な値:
  10. - `````missing`````: インデックスに存在しないサジェストテキスト用語の提案のみを提供します(デフォルト)。
  11. - `````popular`````: 元のサジェストテキスト用語よりも多くの文書に出現する提案のみを提案します。
  12. - `````always`````: サジェストテキスト内の用語に基づいて一致する提案を提案します。
  13. #### Other term suggest options:
  14. | | |
  15. | --- | --- |
  16. | `````max_edits````` | 提案として考慮されるために候補提案が持つことができる最大編集距離。12の間の値のみです。他の値は不正なリクエストエラーを引き起こします。デフォルトは2です。 |
  17. | `````prefix_length````` | 提案候補となるために一致する必要がある最小接頭辞文字数。デフォルトは1です。この数を増やすとスペルチェックのパフォーマンスが向上します。通常、誤字は用語の最初に発生しません。 |
  18. | `````min_word_length````` | サジェストテキスト用語が含まれるために必要な最小長さ。デフォルトは`````4`````です。 |
  19. | `````shard_size````` | 各個別シャードから取得される最大提案数を設定します。リデュースフェーズでは、`````size`````オプションに基づいて上位Nの提案のみが返されます。デフォルトは`````size`````オプションです。これを`````size`````よりも高い値に設定すると、パフォーマンスのコストでスペル修正のためのより正確な文書頻度を取得できます。用語がシャード間で分割されるため、スペル修正のシャードレベルの文書頻度は正確でない場合があります。これを増やすと、これらの文書頻度がより正確になります。 |
  20. | `````max_inspections````` | シャードレベルでより多くの候補スペル修正を検査するために`````shard_size`````と掛け算するために使用される係数。パフォーマンスのコストで精度を向上させることができます。デフォルトは5です。 |
  21. | `````min_doc_freq````` | 提案が出現する文書の最小しきい値。この値は絶対数または文書数の相対的な割合として指定できます。これにより、高頻度の用語のみを提案することで品質が向上します。デフォルトは0fで、無効になっています。1より大きい値が指定された場合、数は小数であってはなりません。シャードレベルの文書頻度がこのオプションに使用されます。 |
  22. | `````max_term_freq````` | 提案テキストトークンが含まれるために存在できる文書の最大しきい値。相対的な割合の数(例:0.4)または文書頻度を表す絶対数であることができます。1より大きい値が指定された場合、小数は指定できません。デフォルトは0.01fです。これは、通常正しく綴られている高頻度の用語をスペルチェックから除外するために使用できます。これにより、スペルチェックのパフォーマンスも向上します。シャードレベルの文書頻度がこのオプションに使用されます。 |
  23. | `````string_distance````` | 提案された用語がどれだけ類似しているかを比較するために使用する文字列距離の実装。指定できる5つの可能な値:
  24. - `````internal`````: デフォルトはdamerau\_levenshteinに基づいていますが、インデックス内の用語の文字列距離を比較するために最適化されています。
  25. - `````damerau_levenshtein`````: Damerau-Levenshteinアルゴリズムに基づく文字列距離アルゴリズム。
  26. - `````levenshtein`````: Levenshtein編集距離アルゴリズムに基づく文字列距離アルゴリズム。
  27. - `````jaro_winkler`````: Jaro-Winklerアルゴリズムに基づく文字列距離アルゴリズム。
  28. - `````ngram`````: 文字n-グラムに基づく文字列距離アルゴリズム。
  29. ## Phrase Suggester
  30. `````term`````サジェスターは、特定の文字列距離内でトークンごとに単語の代替を取得するための非常に便利なAPIを提供します。このAPIは、ストリーム内の各トークンに個別にアクセスできるようにし、サジェスト選択はAPI消費者に委ねられます。しかし、しばしば事前に選択された提案が必要であり、エンドユーザーに提示されます。`````phrase`````サジェスターは、`````term`````サジェスターの上に追加のロジックを追加し、`````ngram-language`````モデルに基づいて重み付けされた個々のトークンの代わりに、全体の修正されたフレーズを選択します。実際には、このサジェスターは共起と頻度に基づいてどのトークンを選択するかについてより良い決定を下すことができます。
  31. #### API Example
  32. 一般的に、`````phrase`````サジェスターは機能するために特別なマッピングが必要です。このページの`````phrase`````サジェスターの例では、機能するために次のマッピングが必要です。`````reverse`````アナライザーは、最後の例でのみ使用されます。
  33. #### Python
  34. ``````python
  35. resp = client.indices.create(
  36. index="test",
  37. settings={
  38. "index": {
  39. "number_of_shards": 1,
  40. "analysis": {
  41. "analyzer": {
  42. "trigram": {
  43. "type": "custom",
  44. "tokenizer": "standard",
  45. "filter": [
  46. "lowercase",
  47. "shingle"
  48. ]
  49. },
  50. "reverse": {
  51. "type": "custom",
  52. "tokenizer": "standard",
  53. "filter": [
  54. "lowercase",
  55. "reverse"
  56. ]
  57. }
  58. },
  59. "filter": {
  60. "shingle": {
  61. "type": "shingle",
  62. "min_shingle_size": 2,
  63. "max_shingle_size": 3
  64. }
  65. }
  66. }
  67. }
  68. },
  69. mappings={
  70. "properties": {
  71. "title": {
  72. "type": "text",
  73. "fields": {
  74. "trigram": {
  75. "type": "text",
  76. "analyzer": "trigram"
  77. },
  78. "reverse": {
  79. "type": "text",
  80. "analyzer": "reverse"
  81. }
  82. }
  83. }
  84. }
  85. },
  86. )
  87. print(resp)
  88. resp1 = client.index(
  89. index="test",
  90. refresh=True,
  91. document={
  92. "title": "noble warriors"
  93. },
  94. )
  95. print(resp1)
  96. resp2 = client.index(
  97. index="test",
  98. refresh=True,
  99. document={
  100. "title": "nobel prize"
  101. },
  102. )
  103. print(resp2)
  104. `

Ruby

  1. response = client.indices.create(
  2. index: 'test',
  3. body: {
  4. settings: {
  5. index: {
  6. number_of_shards: 1,
  7. analysis: {
  8. analyzer: {
  9. trigram: {
  10. type: 'custom',
  11. tokenizer: 'standard',
  12. filter: [
  13. 'lowercase',
  14. 'shingle'
  15. ]
  16. },
  17. reverse: {
  18. type: 'custom',
  19. tokenizer: 'standard',
  20. filter: [
  21. 'lowercase',
  22. 'reverse'
  23. ]
  24. }
  25. },
  26. filter: {
  27. shingle: {
  28. type: 'shingle',
  29. min_shingle_size: 2,
  30. max_shingle_size: 3
  31. }
  32. }
  33. }
  34. }
  35. },
  36. mappings: {
  37. properties: {
  38. title: {
  39. type: 'text',
  40. fields: {
  41. trigram: {
  42. type: 'text',
  43. analyzer: 'trigram'
  44. },
  45. reverse: {
  46. type: 'text',
  47. analyzer: 'reverse'
  48. }
  49. }
  50. }
  51. }
  52. }
  53. }
  54. )
  55. puts response
  56. response = client.index(
  57. index: 'test',
  58. refresh: true,
  59. body: {
  60. title: 'noble warriors'
  61. }
  62. )
  63. puts response
  64. response = client.index(
  65. index: 'test',
  66. refresh: true,
  67. body: {
  68. title: 'nobel prize'
  69. }
  70. )
  71. puts response

Js

  1. const response = await client.indices.create({
  2. index: "test",
  3. settings: {
  4. index: {
  5. number_of_shards: 1,
  6. analysis: {
  7. analyzer: {
  8. trigram: {
  9. type: "custom",
  10. tokenizer: "standard",
  11. filter: ["lowercase", "shingle"],
  12. },
  13. reverse: {
  14. type: "custom",
  15. tokenizer: "standard",
  16. filter: ["lowercase", "reverse"],
  17. },
  18. },
  19. filter: {
  20. shingle: {
  21. type: "shingle",
  22. min_shingle_size: 2,
  23. max_shingle_size: 3,
  24. },
  25. },
  26. },
  27. },
  28. },
  29. mappings: {
  30. properties: {
  31. title: {
  32. type: "text",
  33. fields: {
  34. trigram: {
  35. type: "text",
  36. analyzer: "trigram",
  37. },
  38. reverse: {
  39. type: "text",
  40. analyzer: "reverse",
  41. },
  42. },
  43. },
  44. },
  45. },
  46. });
  47. console.log(response);
  48. const response1 = await client.index({
  49. index: "test",
  50. refresh: "true",
  51. document: {
  52. title: "noble warriors",
  53. },
  54. });
  55. console.log(response1);
  56. const response2 = await client.index({
  57. index: "test",
  58. refresh: "true",
  59. document: {
  60. title: "nobel prize",
  61. },
  62. });
  63. console.log(response2);

Console

  1. PUT test
  2. {
  3. "settings": {
  4. "index": {
  5. "number_of_shards": 1,
  6. "analysis": {
  7. "analyzer": {
  8. "trigram": {
  9. "type": "custom",
  10. "tokenizer": "standard",
  11. "filter": ["lowercase","shingle"]
  12. },
  13. "reverse": {
  14. "type": "custom",
  15. "tokenizer": "standard",
  16. "filter": ["lowercase","reverse"]
  17. }
  18. },
  19. "filter": {
  20. "shingle": {
  21. "type": "shingle",
  22. "min_shingle_size": 2,
  23. "max_shingle_size": 3
  24. }
  25. }
  26. }
  27. }
  28. },
  29. "mappings": {
  30. "properties": {
  31. "title": {
  32. "type": "text",
  33. "fields": {
  34. "trigram": {
  35. "type": "text",
  36. "analyzer": "trigram"
  37. },
  38. "reverse": {
  39. "type": "text",
  40. "analyzer": "reverse"
  41. }
  42. }
  43. }
  44. }
  45. }
  46. }
  47. POST test/_doc?refresh=true
  48. {"title": "noble warriors"}
  49. POST test/_doc?refresh=true
  50. {"title": "nobel prize"}

アナライザーとマッピングが設定されると、phraseサジェスターをtermサジェスターを使用するのと同じ場所で使用できます。

Python

  1. resp = client.search(
  2. index="test",
  3. suggest={
  4. "text": "noble prize",
  5. "simple_phrase": {
  6. "phrase": {
  7. "field": "title.trigram",
  8. "size": 1,
  9. "gram_size": 3,
  10. "direct_generator": [
  11. {
  12. "field": "title.trigram",
  13. "suggest_mode": "always"
  14. }
  15. ],
  16. "highlight": {
  17. "pre_tag": "<em>",
  18. "post_tag": "</em>"
  19. }
  20. }
  21. }
  22. },
  23. )
  24. print(resp)

Js

  1. const response = await client.search({
  2. index: "test",
  3. suggest: {
  4. text: "noble prize",
  5. simple_phrase: {
  6. phrase: {
  7. field: "title.trigram",
  8. size: 1,
  9. gram_size: 3,
  10. direct_generator: [
  11. {
  12. field: "title.trigram",
  13. suggest_mode: "always",
  14. },
  15. ],
  16. highlight: {
  17. pre_tag: "<em>",
  18. post_tag: "</em>",
  19. },
  20. },
  21. },
  22. },
  23. });
  24. console.log(response);

Console

  1. POST test/_search
  2. {
  3. "suggest": {
  4. "text": "noble prize",
  5. "simple_phrase": {
  6. "phrase": {
  7. "field": "title.trigram",
  8. "size": 1,
  9. "gram_size": 3,
  10. "direct_generator": [ {
  11. "field": "title.trigram",
  12. "suggest_mode": "always"
  13. } ],
  14. "highlight": {
  15. "pre_tag": "<em>",
  16. "post_tag": "</em>"
  17. }
  18. }
  19. }
  20. }
  21. }

レスポンスには、最も可能性の高いスペル修正によってスコア付けされた提案が含まれています。この場合、期待される修正「ノーベル賞」を受け取りました。

Console-Result

  1. {
  2. "_shards": ...
  3. "hits": ...
  4. "timed_out": false,
  5. "took": 3,
  6. "suggest": {
  7. "simple_phrase" : [
  8. {
  9. "text" : "noble prize",
  10. "offset" : 0,
  11. "length" : 11,
  12. "options" : [ {
  13. "text" : "nobel prize",
  14. "highlighted": "<em>nobel</em> prize",
  15. "score" : 0.48614594
  16. }]
  17. }
  18. ]
  19. }
  20. }

Basic Phrase suggest API parameters

field 言語モデルのn-グラムルックアップに使用されるフィールドの名前。サジェスターはこのフィールドを使用して修正をスコアリングする統計を取得します。このフィールドは必須です。
gram_size fieldのn-グラム(シングル)サイズの最大値を設定します。フィールドにn-グラム(シングル)が含まれていない場合、これは省略するか1に設定する必要があります。Elasticsearchは、指定されたfieldに基づいてグラムサイズを検出しようとします。フィールドがshingleフィルターを使用している場合、gram_sizeは明示的に設定されていない場合、max_shingle_sizeに設定されます。
real_word_error_likelihood 用語が辞書に存在していても誤って綴られる可能性。デフォルトは0.95で、実際の単語の5%が誤って綴られています。
confidence 信頼レベルは、他のサジェスト候補のしきい値として使用される入力フレーズスコアに適用される係数を定義します。しきい値よりもスコアが高い候補のみが結果に含まれます。たとえば、1.0の信頼レベルは、入力フレーズよりもスコアが高い提案のみを返します。0.0に設定すると、上位Nの候補が返されます。デフォルトは1.0です。
max_errors 修正を形成するために誤って綴られていると見なされる用語の最大割合。このメソッドは、実際のクエリ用語の割合として[0..1)の範囲内の浮動小数点値を受け入れるか、クエリ用語の絶対数として>=1の数値を受け入れます。デフォルトは1.0に設定されており、誤って綴られた用語が1つだけの修正が返されます。これを高く設定しすぎると、パフォーマンスに悪影響を与える可能性があります。12のような低い値が推奨されます。そうでなければ、サジェスト呼び出しにかかる時間がクエリ実行にかかる時間を超える可能性があります。
separator ビグラムフィールド内の用語を区切るために使用されるセパレーター。設定されていない場合、ホワイトスペース文字がセパレーターとして使用されます。
size 各個別のクエリ用語に対して生成される候補の数。35のような低い数は通常良好な結果を生み出します。これを上げると、より高い編集距離の用語が出てくる可能性があります。デフォルトは5です。
analyzer サジェストテキストを分析するためのアナライザーを設定します。デフォルトはfieldを介して渡されたサジェストフィールドの検索アナライザーです。
shard_size 各個別シャードから取得される提案された用語の最大数を設定します。リデュースフェーズでは、sizeオプションに基づいて上位Nの提案のみが返されます。デフォルトは5です。
text 提案を提供するためのテキスト/クエリを設定します。
highlight サジェストハイライトを設定します。提供されていない場合、highlightedフィールドは返されません。提供されている場合、pre_tagpost_tagを正確に含む必要があり、変更されたトークンの周りにラップされます。複数のトークンが連続して変更された場合、変更されたトークンのフレーズ全体がラップされ、各トークンではなくなります。

| collate | 指定されたqueryに対して各提案をチェックし、インデックスに一致する文書が存在しない提案をプルーニングします。提案のコレートクエリは、提案が生成されたローカルシャードでのみ実行されます。queryは指定する必要があり、テンプレート化できます。
検索テンプレートを参照してください。現在の提案は自動的に{{suggestion}}変数として利用可能になり、クエリで使用する必要があります。独自のテンプレートparamsを指定することもできます。suggestion値は、指定した変数に追加されます。さらに、pruneを指定して、すべてのフレーズ提案が返されるかどうかを制御できます。trueに設定すると、提案には追加のオプションcollate_matchがあり、フレーズに一致する文書が見つかった場合はtrue、そうでない場合はfalseになります。

  1. #### Python
  2. ``````python
  3. resp = client.search(
  4. index="test",
  5. suggest={
  6. "text": "noble prize",
  7. "simple_phrase": {
  8. "phrase": {
  9. "field": "title.trigram",
  10. "size": 1,
  11. "direct_generator": [
  12. {
  13. "field": "title.trigram",
  14. "suggest_mode": "always",
  15. "min_word_length": 1
  16. }
  17. ],
  18. "collate": {
  19. "query": {
  20. "source": {
  21. "match": {
  22. "{{field_name}}": "{{suggestion}}"
  23. }
  24. }
  25. },
  26. "params": {
  27. "field_name": "title"
  28. },
  29. "prune": True
  30. }
  31. }
  32. }
  33. },
  34. )
  35. print(resp)
  36. `

Js

  1. const response = await client.search({
  2. index: "test",
  3. suggest: {
  4. text: "noble prize",
  5. simple_phrase: {
  6. phrase: {
  7. field: "title.trigram",
  8. size: 1,
  9. direct_generator: [
  10. {
  11. field: "title.trigram",
  12. suggest_mode: "always",
  13. min_word_length: 1,
  14. },
  15. ],
  16. collate: {
  17. query: {
  18. source: {
  19. match: {
  20. "{{field_name}}": "{{suggestion}}",
  21. },
  22. },
  23. },
  24. params: {
  25. field_name: "title",
  26. },
  27. prune: true,
  28. },
  29. },
  30. },
  31. },
  32. });
  33. console.log(response);

Console

  1. POST test/_search
  2. {
  3. "suggest": {
  4. "text" : "noble prize",
  5. "simple_phrase" : {
  6. "phrase" : {
  7. "field" : "title.trigram",
  8. "size" : 1,
  9. "direct_generator" : [ {
  10. "field" : "title.trigram",
  11. "suggest_mode" : "always",
  12. "min_word_length" : 1
  13. } ],
  14. "collate": {
  15. "query": {
  16. "source" : {
  17. "match": {
  18. "{{field_name}}" : "{{suggestion}}"
  19. }
  20. }
  21. },
  22. "params": {"field_name" : "title"},
  23. "prune": true
  24. }
  25. }
  26. }
  27. }
  28. }
このクエリは、各提案ごとに1回実行されます。
{{suggestion}}変数は、各提案のテキストに置き換えられます。
追加のfield_name変数がparamsで指定され、matchクエリで使用されます。
すべての提案は、生成されたフレーズが文書に一致したかどうかを示す追加のcollate_matchオプションと共に返されます。

Smoothing Models

  1. | | |
  2. | --- | --- |
  3. | `````stupid_backoff````` | 高次のカウントが`````0`````の場合、低次のn-グラムモデルにバックオフし、低次のn-グラムモデルを定数因子で割引く単純なバックオフモデル。デフォルトの`````discount``````````0.4`````です。Stupid Backoffがデフォルトモデルです。 |
  4. | `````laplace````` | すべてのカウントに定数(通常は`````1.0`````またはそれ以下)を追加して重みをバランスさせる加法スムージングモデル。デフォルトの`````alpha``````````0.5`````です。 |
  5. | `````linear_interpolation````` | ユーザーが提供した重み(ラムダ)に基づいて、ユニグラム、バイグラム、トライグラムの加重平均を取るスムージングモデル。線形補間にはデフォルト値はありません。すべてのパラメータ(`````trigram_lambda``````````bigram_lambda``````````unigram_lambda`````)を提供する必要があります。
  6. #### Python
  7. ``````python
  8. resp = client.search(
  9. index="test",
  10. suggest={
  11. "text": "obel prize",
  12. "simple_phrase": {
  13. "phrase": {
  14. "field": "title.trigram",
  15. "size": 1,
  16. "smoothing": {
  17. "laplace": {
  18. "alpha": 0.7
  19. }
  20. }
  21. }
  22. }
  23. },
  24. )
  25. print(resp)
  26. `

Js

  1. const response = await client.search({
  2. index: "test",
  3. suggest: {
  4. text: "obel prize",
  5. simple_phrase: {
  6. phrase: {
  7. field: "title.trigram",
  8. size: 1,
  9. smoothing: {
  10. laplace: {
  11. alpha: 0.7,
  12. },
  13. },
  14. },
  15. },
  16. },
  17. });
  18. console.log(response);

Console

  1. POST test/_search
  2. {
  3. "suggest": {
  4. "text" : "obel prize",
  5. "simple_phrase" : {
  6. "phrase" : {
  7. "field" : "title.trigram",
  8. "size" : 1,
  9. "smoothing" : {
  10. "laplace" : {
  11. "alpha" : 0.7
  12. }
  13. }
  14. }
  15. }
  16. }
  17. }

Candidate Generators

  1. 現在、`````direct_generator`````のみがサポートされている候補生成器のタイプです。フレーズサジェストAPIは、`````direct_generator`````キーの下に生成器のリストを受け入れます。リスト内の各生成器は、元のテキスト内の用語ごとに呼び出されます。
  2. #### Direct Generators
  3. 直接生成器は、次のパラメータをサポートします:
  4. | | |
  5. | --- | --- |
  6. | `````field````` | 候補提案を取得するフィールド。これはグローバルまたは提案ごとに設定する必要がある必須オプションです。 |
  7. | `````size````` | サジェストテキストトークンごとに返される最大修正数。 |
  8. | `````suggest_mode````` | サジェストモードは、各シャードで生成された提案に含まれる提案を制御します。`````always`````以外のすべての値は、各シャードでテストするために少ない提案を生成するための最適化と見なすことができ、各シャードで生成された提案を組み合わせるときに再チェックされません。したがって、`````missing`````は、他のシャードがそれらを含んでいても、シャードに存在しない用語の提案を生成します。これらは`````confidence`````を使用してフィルタリングする必要があります。指定できる3つの可能な値:<br>- `````missing`````: シャードに存在しない用語の提案のみを生成します。これがデフォルトです。<br>- `````popular`````: 元の用語よりも多くの文書に出現する用語のみを提案します。<br>- `````always`````: サジェストテキスト内の用語に基づいて一致する提案を提案します。 |
  9. | `````max_edits````` | 提案として考慮されるために候補提案が持つことができる最大編集距離。12の間の値のみです。他の値は不正なリクエストエラーを引き起こします。デフォルトは2です。 |
  10. | `````prefix_length````` | 提案候補となるために一致する必要がある最小接頭辞文字数。デフォルトは1です。この数を増やすとスペルチェックのパフォーマンスが向上します。通常、誤字は用語の最初に発生しません。 |
  11. | `````min_word_length````` | サジェストテキスト用語が含まれるために必要な最小長さ。デフォルトは4です。 |
  12. | `````max_inspections````` | シャードレベルでより多くの候補スペル修正を検査するために`````shard_size`````と掛け算するために使用される係数。パフォーマンスのコストで精度を向上させることができます。デフォルトは5です。 |
  13. | `````min_doc_freq````` | 提案が出現する文書の最小しきい値。この値は絶対数または文書数の相対的な割合として指定できます。これにより、高頻度の用語のみを提案することで品質が向上します。デフォルトは0fで、無効になっています。1より大きい値が指定された場合、数は小数であってはなりません。シャードレベルの文書頻度がこのオプションに使用されます。 |
  14. | `````max_term_freq````` | 提案テキストトークンが含まれるために存在できる文書の最大しきい値。相対的な割合の数(例:0.4)または文書頻度を表す絶対数であることができます。1より大きい値が指定された場合、小数は指定できません。デフォルトは0.01fです。これは、通常正しく綴られている高頻度の用語をスペルチェックから除外するために使用できます。これにより、スペルチェックのパフォーマンスも向上します。シャードレベルの文書頻度がこのオプションに使用されます。 |
  15. | `````pre_filter````` | この候補生成器に渡される各トークンに適用されるフィルター(アナライザー)。このフィルターは、候補が生成される前に元のトークンに適用されます。 |
  16. | `````post_filter````` | 実際のフレーズスコアラーに渡される前に生成されたトークンに適用されるフィルター(アナライザー)。
  17. 以下の例は、2つの生成器を持つ`````phrase`````サジェスト呼び出しを示しています。最初のものは、通常のインデックス用語を含むフィールドを使用し、2番目のものは`````reverse`````フィルターを使用してインデックスされた用語を使用します(トークンは逆順にインデックスされます)。これは、直接生成器の制限を克服するために使用され、高性能の提案を提供するために定数接頭辞を必要とします。`````pre_filter``````````post_filter`````オプションは、通常のアナライザー名を受け入れます。
  18. #### Python
  19. ``````python
  20. resp = client.search(
  21. index="test",
  22. suggest={
  23. "text": "obel prize",
  24. "simple_phrase": {
  25. "phrase": {
  26. "field": "title.trigram",
  27. "size": 1,
  28. "direct_generator": [
  29. {
  30. "field": "title.trigram",
  31. "suggest_mode": "always"
  32. },
  33. {
  34. "field": "title.reverse",
  35. "suggest_mode": "always",
  36. "pre_filter": "reverse",
  37. "post_filter": "reverse"
  38. }
  39. ]
  40. }
  41. }
  42. },
  43. )
  44. print(resp)
  45. `

Js

  1. const response = await client.search({
  2. index: "test",
  3. suggest: {
  4. text: "obel prize",
  5. simple_phrase: {
  6. phrase: {
  7. field: "title.trigram",
  8. size: 1,
  9. direct_generator: [
  10. {
  11. field: "title.trigram",
  12. suggest_mode: "always",
  13. },
  14. {
  15. field: "title.reverse",
  16. suggest_mode: "always",
  17. pre_filter: "reverse",
  18. post_filter: "reverse",
  19. },
  20. ],
  21. },
  22. },
  23. },
  24. });
  25. console.log(response);

Console

  1. POST test/_search
  2. {
  3. "suggest": {
  4. "text" : "obel prize",
  5. "simple_phrase" : {
  6. "phrase" : {
  7. "field" : "title.trigram",
  8. "size" : 1,
  9. "direct_generator" : [ {
  10. "field" : "title.trigram",
  11. "suggest_mode" : "always"
  12. }, {
  13. "field" : "title.reverse",
  14. "suggest_mode" : "always",
  15. "pre_filter" : "reverse",
  16. "post_filter" : "reverse"
  17. } ]
  18. }
  19. }
  20. }
  21. }

pre_filterpost_filterは、候補が生成された後に同義語を注入するためにも使用できます。たとえば、クエリcaptain usqに対して、用語usqの候補usaを生成することができ、これはamericaの同義語です。これにより、このフレーズが十分に高いスコアを持っている場合、captain americaをユーザーに提示できます。

Completion Suggester

  1. 理想的には、自動補完機能は、ユーザーがすでに入力した内容に関連する即時フィードバックを提供するために、ユーザーが入力する速度と同じくらい速くあるべきです。したがって、`````completion`````サジェスターは速度の最適化が行われています。サジェスターは、高速なルックアップを可能にするデータ構造を使用しますが、構築にはコストがかかり、メモリに保存されます。
  2. #### Mapping
  3. [`````completion`````サジェスター](39d4e7248968ca4f.md#completion-suggester)を使用するには、提案を生成したいフィールドを`````completion`````タイプとしてマッピングします。これにより、フィールド値が高速補完のためにインデックスされます。
  4. #### Python
  5. ``````python
  6. resp = client.indices.create(
  7. index="music",
  8. mappings={
  9. "properties": {
  10. "suggest": {
  11. "type": "completion"
  12. }
  13. }
  14. },
  15. )
  16. print(resp)
  17. `

Ruby

  1. response = client.indices.create(
  2. index: 'music',
  3. body: {
  4. mappings: {
  5. properties: {
  6. suggest: {
  7. type: 'completion'
  8. }
  9. }
  10. }
  11. }
  12. )
  13. puts response

Js

  1. const response = await client.indices.create({
  2. index: "music",
  3. mappings: {
  4. properties: {
  5. suggest: {
  6. type: "completion",
  7. },
  8. },
  9. },
  10. });
  11. console.log(response);

Console

  1. PUT music
  2. {
  3. "mappings": {
  4. "properties": {
  5. "suggest": {
  6. "type": "completion"
  7. }
  8. }
  9. }
  10. }

Parameters for completion fields

  1. | | |
  2. | --- | --- |
  3. | [`````analyzer`````](/read/elasticsearch-8-15/df0c1a6ddee71929.md "analyzer") | 使用するインデックスアナライザー。デフォルトは`````simple`````です。 |
  4. | [`````search_analyzer`````](/read/elasticsearch-8-15/b0cfe1799c03b42e.md "search_analyzer") | 使用する検索アナライザー。デフォルトは`````analyzer`````の値です。 |
  5. | `````preserve_separators````` | セパレーターを保持します。デフォルトは`````true`````です。無効にすると、`````foof`````の提案を行う場合、`````Foo Fighters`````で始まるフィールドを見つけることができます。 |
  6. | `````preserve_position_increments````` | 位置のインクリメントを有効にします。デフォルトは`````true`````です。無効にすると、ストップワードアナライザーを使用している場合、`````The Beatles`````の提案を行う場合、`````b`````で始まるフィールドを取得することができます。**注意**:データを豊かにすることができる場合、`````Beatles``````````The Beatles`````2つの入力をインデックスすることで、単純なアナライザーを変更する必要はありません。 |
  7. | `````max_input_length````` | 単一の入力の長さを制限します。デフォルトは`````50````` UTF-16コードポイントです。この制限は、基礎となるデータ構造が膨張するのを防ぐために、インデックス時にのみ使用されます。ほとんどのユースケースは、デフォルト値によって影響を受けません。接頭辞補完は、通常、数文字以上の接頭辞に成長することはほとんどありません。
  8. #### Indexing
  9. 提案は他のフィールドと同様にインデックスします。提案は、`````input`````とオプションの`````weight`````属性で構成されます。`````input`````は、提案クエリによって一致することが期待されるテキストであり、`````weight`````は提案がどのようにスコアリングされるかを決定します。提案をインデックスする方法は次のとおりです:
  10. #### Python
  11. ``````python
  12. resp = client.index(
  13. index="music",
  14. id="1",
  15. refresh=True,
  16. document={
  17. "suggest": {
  18. "input": [
  19. "Nevermind",
  20. "Nirvana"
  21. ],
  22. "weight": 34
  23. }
  24. },
  25. )
  26. print(resp)
  27. `

Ruby

  1. response = client.index(
  2. index: 'music',
  3. id: 1,
  4. refresh: true,
  5. body: {
  6. suggest: {
  7. input: [
  8. 'Nevermind',
  9. 'Nirvana'
  10. ],
  11. weight: 34
  12. }
  13. }
  14. )
  15. puts response

Js

  1. const response = await client.index({
  2. index: "music",
  3. id: 1,
  4. refresh: "true",
  5. document: {
  6. suggest: {
  7. input: ["Nevermind", "Nirvana"],
  8. weight: 34,
  9. },
  10. },
  11. });
  12. console.log(response);

Console

  1. PUT music/_doc/1?refresh
  2. {
  3. "suggest" : {
  4. "input": [ "Nevermind", "Nirvana" ],
  5. "weight" : 34
  6. }
  7. }

サポートされている次のパラメータ:

input 保存する入力。これは文字列の配列または単一の文字列である可能性があります。このフィールドは必須です。この値には、次のUTF-16制御文字を含めることはできません:
- \u0000(null)
- \u001f(情報区切り子1)
- \u001e(情報区切り子2)

| weight | 正の整数または正の整数を含む文字列で、重みを定義し、提案をランク付けすることができます。このフィールドはオプションです。

ドキュメントに対して複数の提案を次のようにインデックスできます:

Python

  1. resp = client.index(
  2. index="music",
  3. id="1",
  4. refresh=True,
  5. document={
  6. "suggest": [
  7. {
  8. "input": "Nevermind",
  9. "weight": 10
  10. },
  11. {
  12. "input": "Nirvana",
  13. "weight": 3
  14. }
  15. ]
  16. },
  17. )
  18. print(resp)

Ruby

  1. response = client.index(
  2. index: 'music',
  3. id: 1,
  4. refresh: true,
  5. body: {
  6. suggest: [
  7. {
  8. input: 'Nevermind',
  9. weight: 10
  10. },
  11. {
  12. input: 'Nirvana',
  13. weight: 3
  14. }
  15. ]
  16. }
  17. )
  18. puts response

Js

  1. const response = await client.index({
  2. index: "music",
  3. id: 1,
  4. refresh: "true",
  5. document: {
  6. suggest: [
  7. {
  8. input: "Nevermind",
  9. weight: 10,
  10. },
  11. {
  12. input: "Nirvana",
  13. weight: 3,
  14. },
  15. ],
  16. },
  17. });
  18. console.log(response);

Console

  1. PUT music/_doc/1?refresh
  2. {
  3. "suggest": [
  4. {
  5. "input": "Nevermind",
  6. "weight": 10
  7. },
  8. {
  9. "input": "Nirvana",
  10. "weight": 3
  11. }
  12. ]
  13. }

次の省略形を使用できます。提案に重みを指定することはできません。

Python

  1. resp = client.index(
  2. index="music",
  3. id="1",
  4. refresh=True,
  5. document={
  6. "suggest": [
  7. "Nevermind",
  8. "Nirvana"
  9. ]
  10. },
  11. )
  12. print(resp)

Ruby

  1. response = client.index(
  2. index: 'music',
  3. id: 1,
  4. refresh: true,
  5. body: {
  6. suggest: [
  7. 'Nevermind',
  8. 'Nirvana'
  9. ]
  10. }
  11. )
  12. puts response

Js

  1. const response = await client.index({
  2. index: "music",
  3. id: 1,
  4. refresh: "true",
  5. document: {
  6. suggest: ["Nevermind", "Nirvana"],
  7. },
  8. });
  9. console.log(response);

Console

  1. PUT music/_doc/1?refresh
  2. {
  3. "suggest" : [ "Nevermind", "Nirvana" ]
  4. }

Querying

提案は通常通り機能しますが、サジェストタイプをcompletionとして指定する必要があります。提案はほぼリアルタイムであり、新しい提案はリフレッシュによって表示される可能性があり、一度削除された文書は決して表示されません。このリクエスト:

Python

  1. resp = client.search(
  2. index="music",
  3. pretty=True,
  4. suggest={
  5. "song-suggest": {
  6. "prefix": "nir",
  7. "completion": {
  8. "field": "suggest"
  9. }
  10. }
  11. },
  12. )
  13. print(resp)

Ruby

  1. response = client.search(
  2. index: 'music',
  3. pretty: true,
  4. body: {
  5. suggest: {
  6. "song-suggest": {
  7. prefix: 'nir',
  8. completion: {
  9. field: 'suggest'
  10. }
  11. }
  12. }
  13. }
  14. )
  15. puts response

Js

  1. const response = await client.search({
  2. index: "music",
  3. pretty: "true",
  4. suggest: {
  5. "song-suggest": {
  6. prefix: "nir",
  7. completion: {
  8. field: "suggest",
  9. },
  10. },
  11. },
  12. });
  13. console.log(response);

Console

  1. POST music/_search?pretty
  2. {
  3. "suggest": {
  4. "song-suggest": {
  5. "prefix": "nir",
  6. "completion": {
  7. "field": "suggest"
  8. }
  9. }
  10. }
  11. }
提案を検索するために使用される接頭辞
提案の種類
提案を検索するフィールドの名前

このレスポンスを返します:

Console-Result

  1. {
  2. "_shards" : {
  3. "total" : 1,
  4. "successful" : 1,
  5. "skipped" : 0,
  6. "failed" : 0
  7. },
  8. "hits": ...
  9. "took": 2,
  10. "timed_out": false,
  11. "suggest": {
  12. "song-suggest" : [ {
  13. "text" : "nir",
  14. "offset" : 0,
  15. "length" : 3,
  16. "options" : [ {
  17. "text" : "Nirvana",
  18. "_index": "music",
  19. "_id": "1",
  20. "_score": 1.0,
  21. "_source": {
  22. "suggest": ["Nevermind", "Nirvana"]
  23. }
  24. } ]
  25. } ]
  26. }
  27. }

_source メタデータフィールドは有効にする必要があります。これはデフォルトの動作であり、_source を提案と共に返すことを可能にします。

提案のために設定された重みは _score として返されます。text フィールドは、インデックスされた提案の input を使用します。提案はデフォルトで完全なドキュメント _source を返します。_source のサイズは、ディスクフェッチとネットワーク転送のオーバーヘッドのためにパフォーマンスに影響を与える可能性があります。ネットワークのオーバーヘッドを削減するために、ソースフィルタリングを使用して _source から不要なフィールドをフィルタリングし、_source のサイズを最小限に抑えてください。_suggest エンドポイントはソースフィルタリングをサポートしていませんが、_search エンドポイントで suggest を使用することは可能です:

Python

  1. resp = client.search(
  2. index="music",
  3. source="suggest",
  4. suggest={
  5. "song-suggest": {
  6. "prefix": "nir",
  7. "completion": {
  8. "field": "suggest",
  9. "size": 5
  10. }
  11. }
  12. },
  13. )
  14. print(resp)

Ruby

  1. response = client.search(
  2. index: 'music',
  3. body: {
  4. _source: 'suggest',
  5. suggest: {
  6. "song-suggest": {
  7. prefix: 'nir',
  8. completion: {
  9. field: 'suggest',
  10. size: 5
  11. }
  12. }
  13. }
  14. }
  15. )
  16. puts response

Js

  1. const response = await client.search({
  2. index: "music",
  3. _source: "suggest",
  4. suggest: {
  5. "song-suggest": {
  6. prefix: "nir",
  7. completion: {
  8. field: "suggest",
  9. size: 5,
  10. },
  11. },
  12. },
  13. });
  14. console.log(response);

Console

  1. POST music/_search
  2. {
  3. "_source": "suggest",
  4. "suggest": {
  5. "song-suggest": {
  6. "prefix": "nir",
  7. "completion": {
  8. "field": "suggest",
  9. "size": 5
  10. }
  11. }
  12. }
  13. }
ソースをフィルタリングして suggest フィールドのみを返す
提案を検索するフィールドの名前
返す提案の数

次のようになります:

Console-Result

  1. {
  2. "took": 6,
  3. "timed_out": false,
  4. "_shards": {
  5. "total": 1,
  6. "successful": 1,
  7. "skipped": 0,
  8. "failed": 0
  9. },
  10. "hits": {
  11. "total": {
  12. "value": 0,
  13. "relation": "eq"
  14. },
  15. "max_score": null,
  16. "hits": []
  17. },
  18. "suggest": {
  19. "song-suggest": [ {
  20. "text": "nir",
  21. "offset": 0,
  22. "length": 3,
  23. "options": [ {
  24. "text": "Nirvana",
  25. "_index": "music",
  26. "_id": "1",
  27. "_score": 1.0,
  28. "_source": {
  29. "suggest": [ "Nevermind", "Nirvana" ]
  30. }
  31. } ]
  32. } ]
  33. }
  34. }

基本的な補完サジェスタークエリは、以下のパラメータをサポートしています:

field クエリを実行するフィールドの名前(必須)。
size 返す提案の数(デフォルトは 5)。
skip_duplicates 重複提案をフィルタリングするかどうか(デフォルトは false)。

補完サジェスターはインデックス内のすべてのドキュメントを考慮します。特定のドキュメントのサブセットをクエリする方法については、コンテキストサジェスターを参照してください。

複数のシャードにまたがる補完クエリの場合、サジェストは2つのフェーズで実行され、最後のフェーズでシャードから関連するドキュメントを取得します。これは、サジェストが複数のシャードにまたがる場合、ドキュメントフェッチのオーバーヘッドのために単一のシャードに対して補完リクエストを実行する方がパフォーマンスが良いことを意味します。補完のパフォーマンスを最適化するためには、補完を単一のシャードインデックスにインデックスすることをお勧めします。シャードサイズによるヒープ使用量が高い場合でも、補完パフォーマンスを最適化するのではなく、インデックスを複数のシャードに分割することをお勧めします。

Skip duplicate suggestions

クエリは異なるドキュメントからの重複提案を返すことがあります。この動作を変更するには、skip_duplicates を true に設定することが可能です。設定すると、このオプションは結果から重複提案を持つドキュメントをフィルタリングします。

Python

  1. resp = client.search(
  2. index="music",
  3. pretty=True,
  4. suggest={
  5. "song-suggest": {
  6. "prefix": "nor",
  7. "completion": {
  8. "field": "suggest",
  9. "skip_duplicates": True
  10. }
  11. }
  12. },
  13. )
  14. print(resp)

Ruby

  1. response = client.search(
  2. index: 'music',
  3. pretty: true,
  4. body: {
  5. suggest: {
  6. "song-suggest": {
  7. prefix: 'nor',
  8. completion: {
  9. field: 'suggest',
  10. skip_duplicates: true
  11. }
  12. }
  13. }
  14. }
  15. )
  16. puts response

Js

  1. const response = await client.search({
  2. index: "music",
  3. pretty: "true",
  4. suggest: {
  5. "song-suggest": {
  6. prefix: "nor",
  7. completion: {
  8. field: "suggest",
  9. skip_duplicates: true,
  10. },
  11. },
  12. },
  13. });
  14. console.log(response);

Console

  1. POST music/_search?pretty
  2. {
  3. "suggest": {
  4. "song-suggest": {
  5. "prefix": "nor",
  6. "completion": {
  7. "field": "suggest",
  8. "skip_duplicates": true
  9. }
  10. }
  11. }
  12. }

true に設定すると、このオプションは検索を遅くする可能性があります。なぜなら、トップ N を見つけるために訪問する必要がある提案が増えるからです。

Fuzzy queries

補完サジェスターはファジークエリもサポートしています。これは、検索にタイプミスがあっても結果を得ることができることを意味します。

Python

  1. resp = client.search(
  2. index="music",
  3. pretty=True,
  4. suggest={
  5. "song-suggest": {
  6. "prefix": "nor",
  7. "completion": {
  8. "field": "suggest",
  9. "fuzzy": {
  10. "fuzziness": 2
  11. }
  12. }
  13. }
  14. },
  15. )
  16. print(resp)

Ruby

  1. response = client.search(
  2. index: 'music',
  3. pretty: true,
  4. body: {
  5. suggest: {
  6. "song-suggest": {
  7. prefix: 'nor',
  8. completion: {
  9. field: 'suggest',
  10. fuzzy: {
  11. fuzziness: 2
  12. }
  13. }
  14. }
  15. }
  16. }
  17. )
  18. puts response

Js

  1. const response = await client.search({
  2. index: "music",
  3. pretty: "true",
  4. suggest: {
  5. "song-suggest": {
  6. prefix: "nor",
  7. completion: {
  8. field: "suggest",
  9. fuzzy: {
  10. fuzziness: 2,
  11. },
  12. },
  13. },
  14. },
  15. });
  16. console.log(response);

Console

  1. POST music/_search?pretty
  2. {
  3. "suggest": {
  4. "song-suggest": {
  5. "prefix": "nor",
  6. "completion": {
  7. "field": "suggest",
  8. "fuzzy": {
  9. "fuzziness": 2
  10. }
  11. }
  12. }
  13. }
  14. }

クエリ prefix に最も長い接頭辞を共有する提案は、より高いスコアが付けられます。

ファジークエリは特定のファジーパラメータを取ることができます。以下のパラメータがサポートされています:

fuzziness ファジネスファクター、デフォルトは AUTO

許可されている設定については Fuzziness を参照してください。
transpositions true に設定されている場合、転置は2つの変更の代わりに1つの変更としてカウントされ、デフォルトは true
min_length ファジー提案が返される前の入力の最小長さ、デフォルトは 3
prefix_length ファジー代替案のチェックが行われない入力の最小長さ、デフォルトは 1
unicode_aware true の場合、すべての測定(ファジー編集距離、転置、長さなど)は、バイトではなく Unicode コードポイントで測定されます。これは生のバイトよりもわずかに遅く、デフォルトでは false に設定されています。

デフォルト値を維持したいが、ファジーを使用したい場合は、fuzzy: {} または fuzzy: true を使用できます。

Regex queries

補完サジェスターは正規表現クエリもサポートしており、接頭辞を正規表現として表現することができます。

Python

  1. resp = client.search(
  2. index="music",
  3. pretty=True,
  4. suggest={
  5. "song-suggest": {
  6. "regex": "n[ever|i]r",
  7. "completion": {
  8. "field": "suggest"
  9. }
  10. }
  11. },
  12. )
  13. print(resp)

Ruby

  1. response = client.search(
  2. index: 'music',
  3. pretty: true,
  4. body: {
  5. suggest: {
  6. "song-suggest": {
  7. regex: 'n[ever|i]r',
  8. completion: {
  9. field: 'suggest'
  10. }
  11. }
  12. }
  13. }
  14. )
  15. puts response

Js

  1. const response = await client.search({
  2. index: "music",
  3. pretty: "true",
  4. suggest: {
  5. "song-suggest": {
  6. regex: "n[ever|i]r",
  7. completion: {
  8. field: "suggest",
  9. },
  10. },
  11. },
  12. });
  13. console.log(response);

Console

  1. POST music/_search?pretty
  2. {
  3. "suggest": {
  4. "song-suggest": {
  5. "regex": "n[ever|i]r",<br> "completion": {<br> "field": "suggest"<br> }<br> }<br> }<br>}<br>``````<br><br>正規表現クエリは特定の正規表現パラメータを取ることができます。以下のパラメータがサポートされています: <br><br>
  6. | | |
  7. | --- | --- |
  8. | `````flags````` | 可能なフラグは `````ALL`````(デフォルト)、`````ANYSTRING``````````COMPLEMENT`````、<br><br>`````EMPTY``````````INTERSECTION``````````INTERVAL`````、または `````NONE````` です。意味については [regexp-syntax](/read/elasticsearch-8-15/18c0a8d633e2b8f9.md "Regexp query")<br><br>を参照してください。 |
  9. | `````max_determinized_states````` | 正規表現は危険です。なぜなら、無害に見えるものを偶然に作成してしまうことが容易であり、それが Lucene の実行に必要な指数関数的な数の内部決定化オートマトン状態(および対応する RAM CPU)を要求するからです。Lucene `````max_determinized_states````` 設定(デフォルトは 10000)を使用してこれを防ぎます。この制限を引き上げることで、より複雑な正規表現を実行できるようになります。
  10. ## Context Suggester
  11. 補完サジェスターはインデックス内のすべてのドキュメントを考慮しますが、提案を特定の基準でフィルタリングおよび/またはブーストすることが望ましいことがよくあります。たとえば、特定のアーティストによってフィルタリングされた曲のタイトルを提案したり、ジャンルに基づいて曲のタイトルをブーストしたりすることができます。
  12. 提案のフィルタリングおよび/またはブーストを実現するには、補完フィールドを構成する際にコンテキストマッピングを追加できます。補完フィールドに対して複数のコンテキストマッピングを定義できます。各コンテキストマッピングには一意の名前とタイプがあります。2つのタイプがあります: `````category````` `````geo`````。コンテキストマッピングはフィールドマッピングの `````contexts````` パラメータの下で構成されます。
  13. コンテキストを提供することは、コンテキストが有効な補完フィールドをインデックスおよびクエリする際に必須です。
  14. 補完フィールドのコンテキストマッピングの最大許可数は 10 です。
  15. 以下は、各補完フィールドのための2つのコンテキストマッピングを持つタイプを定義します:
  16. #### Python
  17. ``````python
  18. resp = client.indices.create(
  19. index="place",
  20. mappings={
  21. "properties": {
  22. "suggest": {
  23. "type": "completion",
  24. "contexts": [
  25. {
  26. "name": "place_type",
  27. "type": "category"
  28. },
  29. {
  30. "name": "location",
  31. "type": "geo",
  32. "precision": 4
  33. }
  34. ]
  35. }
  36. }
  37. },
  38. )
  39. print(resp)
  40. resp1 = client.indices.create(
  41. index="place_path_category",
  42. mappings={
  43. "properties": {
  44. "suggest": {
  45. "type": "completion",
  46. "contexts": [
  47. {
  48. "name": "place_type",
  49. "type": "category",
  50. "path": "cat"
  51. },
  52. {
  53. "name": "location",
  54. "type": "geo",
  55. "precision": 4,
  56. "path": "loc"
  57. }
  58. ]
  59. },
  60. "loc": {
  61. "type": "geo_point"
  62. }
  63. }
  64. },
  65. )
  66. print(resp1)

Ruby

  1. response = client.indices.create(
  2. index: 'place',
  3. body: {
  4. mappings: {
  5. properties: {
  6. suggest: {
  7. type: 'completion',
  8. contexts: [
  9. {
  10. name: 'place_type',
  11. type: 'category'
  12. },
  13. {
  14. name: 'location',
  15. type: 'geo',
  16. precision: 4
  17. }
  18. ]
  19. }
  20. }
  21. }
  22. }
  23. )
  24. puts response
  25. response = client.indices.create(
  26. index: 'place_path_category',
  27. body: {
  28. mappings: {
  29. properties: {
  30. suggest: {
  31. type: 'completion',
  32. contexts: [
  33. {
  34. name: 'place_type',
  35. type: 'category',
  36. path: 'cat'
  37. },
  38. {
  39. name: 'location',
  40. type: 'geo',
  41. precision: 4,
  42. path: 'loc'
  43. }
  44. ]
  45. },
  46. loc: {
  47. type: 'geo_point'
  48. }
  49. }
  50. }
  51. }
  52. )
  53. puts response

Js

  1. const response = await client.indices.create({
  2. index: "place",
  3. mappings: {
  4. properties: {
  5. suggest: {
  6. type: "completion",
  7. contexts: [
  8. {
  9. name: "place_type",
  10. type: "category",
  11. },
  12. {
  13. name: "location",
  14. type: "geo",
  15. precision: 4,
  16. },
  17. ],
  18. },
  19. },
  20. },
  21. });
  22. console.log(response);
  23. const response1 = await client.indices.create({
  24. index: "place_path_category",
  25. mappings: {
  26. properties: {
  27. suggest: {
  28. type: "completion",
  29. contexts: [
  30. {
  31. name: "place_type",
  32. type: "category",
  33. path: "cat",
  34. },
  35. {
  36. name: "location",
  37. type: "geo",
  38. precision: 4,
  39. path: "loc",
  40. },
  41. ],
  42. },
  43. loc: {
  44. type: "geo_point",
  45. },
  46. },
  47. },
  48. });
  49. console.log(response1);

Console

  1. PUT place
  2. {
  3. "mappings": {
  4. "properties": {
  5. "suggest": {
  6. "type": "completion",
  7. "contexts": [
  8. {
  9. "name": "place_type",
  10. "type": "category"
  11. },
  12. {
  13. "name": "location",
  14. "type": "geo",
  15. "precision": 4
  16. }
  17. ]
  18. }
  19. }
  20. }
  21. }
  22. PUT place_path_category
  23. {
  24. "mappings": {
  25. "properties": {
  26. "suggest": {
  27. "type": "completion",
  28. "contexts": [
  29. {
  30. "name": "place_type",
  31. "type": "category",
  32. "path": "cat"
  33. },
  34. {
  35. "name": "location",
  36. "type": "geo",
  37. "precision": 4,
  38. "path": "loc"
  39. }
  40. ]
  41. },
  42. "loc": {
  43. "type": "geo_point"
  44. }
  45. }
  46. }
  47. }
place_type という名前の category コンテキストを定義し、カテゴリは提案と共に送信される必要があります。
location という名前の geo コンテキストを定義し、カテゴリは提案と共に送信される必要があります。
category という名前の place_type コンテキストを定義し、カテゴリは cat フィールドから読み取られます。
geo という名前の location コンテキストを定義し、カテゴリは loc フィールドから読み取られます。

コンテキストマッピングを追加すると、補完フィールドのインデックスサイズが増加します。補完インデックスは完全にヒープに常駐しており、インデックス統計を使用して補完フィールドインデックスサイズを監視できます。

Category Context

category コンテキストは、インデックス時に提案に1つ以上のカテゴリを関連付けることを可能にします。クエリ時には、提案は関連付けられたカテゴリによってフィルタリングおよびブーストされることができます。

マッピングは、上記の place_type フィールドのように設定されます。path が定義されている場合、カテゴリはドキュメント内のそのパスから読み取られます。そうでない場合、提案フィールドに次のように送信する必要があります:

Python

  1. resp = client.index(
  2. index="place",
  3. id="1",
  4. document={
  5. "suggest": {
  6. "input": [
  7. "timmy's",
  8. "starbucks",
  9. "dunkin donuts"
  10. ],
  11. "contexts": {
  12. "place_type": [
  13. "cafe",
  14. "food"
  15. ]
  16. }
  17. }
  18. },
  19. )
  20. print(resp)

Ruby

  1. response = client.index(
  2. index: 'place',
  3. id: 1,
  4. body: {
  5. suggest: {
  6. input: [
  7. "timmy's",
  8. 'starbucks',
  9. 'dunkin donuts'
  10. ],
  11. contexts: {
  12. place_type: [
  13. 'cafe',
  14. 'food'
  15. ]
  16. }
  17. }
  18. }
  19. )
  20. puts response

Js

  1. const response = await client.index({
  2. index: "place",
  3. id: 1,
  4. document: {
  5. suggest: {
  6. input: ["timmy's", "starbucks", "dunkin donuts"],
  7. contexts: {
  8. place_type: ["cafe", "food"],
  9. },
  10. },
  11. },
  12. });
  13. console.log(response);

Console

  1. PUT place/_doc/1
  2. {
  3. "suggest": {
  4. "input": [ "timmy's", "starbucks", "dunkin donuts" ],
  5. "contexts": {
  6. "place_type": [ "cafe", "food" ]
  7. }
  8. }
  9. }
これらの提案は cafefood カテゴリに関連付けられます。

マッピングに path があった場合、次のインデックスリクエストでカテゴリを追加するのに十分です:

Python

  1. resp = client.index(
  2. index="place_path_category",
  3. id="1",
  4. document={
  5. "suggest": [
  6. "timmy's",
  7. "starbucks",
  8. "dunkin donuts"
  9. ],
  10. "cat": [
  11. "cafe",
  12. "food"
  13. ]
  14. },
  15. )
  16. print(resp)

Ruby

  1. response = client.index(
  2. index: 'place_path_category',
  3. id: 1,
  4. body: {
  5. suggest: [
  6. "timmy's",
  7. 'starbucks',
  8. 'dunkin donuts'
  9. ],
  10. cat: [
  11. 'cafe',
  12. 'food'
  13. ]
  14. }
  15. )
  16. puts response

Js

  1. const response = await client.index({
  2. index: "place_path_category",
  3. id: 1,
  4. document: {
  5. suggest: ["timmy's", "starbucks", "dunkin donuts"],
  6. cat: ["cafe", "food"],
  7. },
  8. });
  9. console.log(response);

Console

  1. PUT place_path_category/_doc/1
  2. {
  3. "suggest": ["timmy's", "starbucks", "dunkin donuts"],
  4. "cat": ["cafe", "food"]
  5. }
これらの提案は cafefood カテゴリに関連付けられます。

コンテキストマッピングが別のフィールドを参照し、カテゴリが明示的にインデックスされている場合、提案は両方のカテゴリセットでインデックスされます。

Category Query

提案は1つ以上のカテゴリによってフィルタリングできます。以下は、複数のカテゴリによって提案をフィルタリングします:

Python

  1. resp = client.search(
  2. index="place",
  3. pretty=True,
  4. suggest={
  5. "place_suggestion": {
  6. "prefix": "tim",
  7. "completion": {
  8. "field": "suggest",
  9. "size": 10,
  10. "contexts": {
  11. "place_type": [
  12. "cafe",
  13. "restaurants"
  14. ]
  15. }
  16. }
  17. }
  18. },
  19. )
  20. print(resp)

Ruby

  1. response = client.search(
  2. index: 'place',
  3. pretty: true,
  4. body: {
  5. suggest: {
  6. place_suggestion: {
  7. prefix: 'tim',
  8. completion: {
  9. field: 'suggest',
  10. size: 10,
  11. contexts: {
  12. place_type: [
  13. 'cafe',
  14. 'restaurants'
  15. ]
  16. }
  17. }
  18. }
  19. }
  20. }
  21. )
  22. puts response

Js

  1. const response = await client.search({
  2. index: "place",
  3. pretty: "true",
  4. suggest: {
  5. place_suggestion: {
  6. prefix: "tim",
  7. completion: {
  8. field: "suggest",
  9. size: 10,
  10. contexts: {
  11. place_type: ["cafe", "restaurants"],
  12. },
  13. },
  14. },
  15. },
  16. });
  17. console.log(response);

Console

  1. POST place/_search?pretty
  2. {
  3. "suggest": {
  4. "place_suggestion": {
  5. "prefix": "tim",
  6. "completion": {
  7. "field": "suggest",
  8. "size": 10,
  9. "contexts": {
  10. "place_type": [ "cafe", "restaurants" ]
  11. }
  12. }
  13. }
  14. }
  15. }

クエリに複数のカテゴリまたはカテゴリコンテキストが設定されている場合、それらは論理和としてマージされます。これは、提案が提供されたコンテキスト値のいずれかを含む場合に一致することを意味します。

特定のカテゴリを持つ提案は、他の提案よりも高くブーストされることがあります。以下は、カテゴリによって提案をフィルタリングし、さらにいくつかのカテゴリに関連付けられた提案をブーストします:

Python

  1. resp = client.search(
  2. index="place",
  3. pretty=True,
  4. suggest={
  5. "place_suggestion": {
  6. "prefix": "tim",
  7. "completion": {
  8. "field": "suggest",
  9. "size": 10,
  10. "contexts": {
  11. "place_type": [
  12. {
  13. "context": "cafe"
  14. },
  15. {
  16. "context": "restaurants",
  17. "boost": 2
  18. }
  19. ]
  20. }
  21. }
  22. }
  23. },
  24. )
  25. print(resp)

Ruby

  1. response = client.search(
  2. index: 'place',
  3. pretty: true,
  4. body: {
  5. suggest: {
  6. place_suggestion: {
  7. prefix: 'tim',
  8. completion: {
  9. field: 'suggest',
  10. size: 10,
  11. contexts: {
  12. place_type: [
  13. {
  14. context: 'cafe'
  15. },
  16. {
  17. context: 'restaurants',
  18. boost: 2
  19. }
  20. ]
  21. }
  22. }
  23. }
  24. }
  25. }
  26. )
  27. puts response

Js

  1. const response = await client.search({
  2. index: "place",
  3. pretty: "true",
  4. suggest: {
  5. place_suggestion: {
  6. prefix: "tim",
  7. completion: {
  8. field: "suggest",
  9. size: 10,
  10. contexts: {
  11. place_type: [
  12. {
  13. context: "cafe",
  14. },
  15. {
  16. context: "restaurants",
  17. boost: 2,
  18. },
  19. ],
  20. },
  21. },
  22. },
  23. },
  24. });
  25. console.log(response);

Console

  1. POST place/_search?pretty
  2. {
  3. "suggest": {
  4. "place_suggestion": {
  5. "prefix": "tim",
  6. "completion": {
  7. "field": "suggest",
  8. "size": 10,
  9. "contexts": {
  10. "place_type": [
  11. { "context": "cafe" },
  12. { "context": "restaurants", "boost": 2 }
  13. ]
  14. }
  15. }
  16. }
  17. }
  18. }
コンテキストクエリは、caferestaurants カテゴリに関連付けられた提案をフィルタリングし、restaurants に関連付けられた提案を 2 の係数でブーストします。

カテゴリ値を受け入れることに加えて、コンテキストクエリは複数のカテゴリコンテキスト条項で構成されることができます。category コンテキスト条項に対してサポートされている以下のパラメータ:


| | |
| —- | —- |
| context | フィルタリング/ブーストするカテゴリの値。

これは必須です。 |
| boost | 提案のスコアをブーストする係数。

スコアはブーストと提案の重みを掛け算して計算され、デフォルトは 1 |
| prefix | カテゴリ値を接頭辞として扱うかどうか。たとえば、true に設定されている場合、type1type2 などのカテゴリをフィルタリングすることができ、type のカテゴリ接頭辞を指定することができます。

デフォルトは false |

提案エントリが複数のコンテキストに一致する場合、最終スコアは一致するコンテキストの中で生成された最大スコアとして計算されます。

Geo location Context

geo コンテキストは、インデックス時に提案に1つ以上のジオポイントまたはジオハッシュを関連付けることを可能にします。クエリ時には、提案は特定のジオロケーションからの距離が一定の範囲内にある場合にフィルタリングおよびブーストされることがあります。

内部的に、ジオポイントは指定された精度でジオハッシュとしてエンコードされます。

Geo Mapping

path 設定に加えて、geo コンテキストマッピングは以下の設定を受け入れます:

precision これはインデックスされるジオハッシュの精度を定義し、距離値(5m10km など)または生のジオハッシュ精度(1..12)として指定できます。

デフォルトは 6 の生のジオハッシュ精度値です。

インデックス時の precision 設定は、クエリ時に使用できる最大ジオハッシュ精度を設定します。

Indexing geo contexts

geo コンテキストは、提案と明示的に設定するか、path パラメータを介してドキュメント内のジオポイントフィールドからインデックスされることができます。複数のジオロケーションコンテキストを提案に関連付けると、各ジオロケーションのために提案がインデックスされます。以下は、2つのジオロケーションコンテキストで提案をインデックスします:

Python

  1. resp = client.index(
  2. index="place",
  3. id="1",
  4. document={
  5. "suggest": {
  6. "input": "timmy's",
  7. "contexts": {
  8. "location": [
  9. {
  10. "lat": 43.6624803,
  11. "lon": -79.3863353
  12. },
  13. {
  14. "lat": 43.6624718,
  15. "lon": -79.3873227
  16. }
  17. ]
  18. }
  19. }
  20. },
  21. )
  22. print(resp)

Ruby

  1. response = client.index(
  2. index: 'place',
  3. id: 1,
  4. body: {
  5. suggest: {
  6. input: "timmy's",
  7. contexts: {
  8. location: [
  9. {
  10. lat: 43.6624803,
  11. lon: -79.3863353
  12. },
  13. {
  14. lat: 43.6624718,
  15. lon: -79.3873227
  16. }
  17. ]
  18. }
  19. }
  20. }
  21. )
  22. puts response

Js

  1. const response = await client.index({
  2. index: "place",
  3. id: 1,
  4. document: {
  5. suggest: {
  6. input: "timmy's",
  7. contexts: {
  8. location: [
  9. {
  10. lat: 43.6624803,
  11. lon: -79.3863353,
  12. },
  13. {
  14. lat: 43.6624718,
  15. lon: -79.3873227,
  16. },
  17. ],
  18. },
  19. },
  20. },
  21. });
  22. console.log(response);

コンソール

  1. PUT place/_doc/1
  2. {
  3. "suggest": {
  4. "input": "timmy's",
  5. "contexts": {
  6. "location": [
  7. {
  8. "lat": 43.6624803,
  9. "lon": -79.3863353
  10. },
  11. {
  12. "lat": 43.6624718,
  13. "lon": -79.3873227
  14. }
  15. ]
  16. }
  17. }
  18. }
Geo location Query

提案は、1つ以上のジオポイントに対してどれだけ近いかに基づいてフィルタリングおよびブーストされることがあります。以下は、ジオポイントのエンコードされたジオハッシュによって表される領域内にある提案をフィルタリングします:

Python

  1. resp = client.search(
  2. index="place",
  3. suggest={
  4. "place_suggestion": {
  5. "prefix": "tim",
  6. "completion": {
  7. "field": "suggest",
  8. "size": 10,
  9. "contexts": {
  10. "location": {
  11. "lat": 43.662,
  12. "lon": -79.38
  13. }
  14. }
  15. }
  16. }
  17. },
  18. )
  19. print(resp)

Ruby

  1. response = client.search(
  2. index: 'place',
  3. body: {
  4. suggest: {
  5. place_suggestion: {
  6. prefix: 'tim',
  7. completion: {
  8. field: 'suggest',
  9. size: 10,
  10. contexts: {
  11. location: {
  12. lat: 43.662,
  13. lon: -79.38
  14. }
  15. }
  16. }
  17. }
  18. }
  19. }
  20. )
  21. puts response

Js

  1. const response = await client.search({
  2. index: "place",
  3. suggest: {
  4. place_suggestion: {
  5. prefix: "tim",
  6. completion: {
  7. field: "suggest",
  8. size: 10,
  9. contexts: {
  10. location: {
  11. lat: 43.662,
  12. lon: -79.38,
  13. },
  14. },
  15. },
  16. },
  17. },
  18. });
  19. console.log(response);

Console

  1. POST place/_search
  2. {
  3. "suggest": {
  4. "place_suggestion": {
  5. "prefix": "tim",
  6. "completion": {
  7. "field": "suggest",
  8. "size": 10,
  9. "contexts": {
  10. "location": {
  11. "lat": 43.662,
  12. "lon": -79.380
  13. }
  14. }
  15. }
  16. }
  17. }
  18. }

低い精度のロケーションがクエリ時に指定されると、その領域内にあるすべての提案が考慮されます。

クエリに複数のカテゴリまたはカテゴリコンテキストが設定されている場合、それらは論理和としてマージされます。これは、提案が提供されたコンテキスト値のいずれかを含む場合に一致することを意味します。

ジオハッシュによって表される領域内にある提案は、他の提案よりも高くブーストされることもあります。以下に示すように:

Python

  1. resp = client.search(
  2. index="place",
  3. pretty=True,
  4. suggest={
  5. "place_suggestion": {
  6. "prefix": "tim",
  7. "completion": {
  8. "field": "suggest",
  9. "size": 10,
  10. "contexts": {
  11. "location": [
  12. {
  13. "lat": 43.6624803,
  14. "lon": -79.3863353,
  15. "precision": 2
  16. },
  17. {
  18. "context": {
  19. "lat": 43.6624803,
  20. "lon": -79.3863353
  21. },
  22. "boost": 2
  23. }
  24. ]
  25. }
  26. }
  27. }
  28. },
  29. )
  30. print(resp)

Ruby

  1. response = client.search(
  2. index: 'place',
  3. pretty: true,
  4. body: {
  5. suggest: {
  6. place_suggestion: {
  7. prefix: 'tim',
  8. completion: {
  9. field: 'suggest',
  10. size: 10,
  11. contexts: {
  12. location: [
  13. {
  14. lat: 43.6624803,
  15. lon: -79.3863353,
  16. precision: 2
  17. },
  18. {
  19. context: {
  20. lat: 43.6624803,
  21. lon: -79.3863353
  22. },
  23. boost: 2
  24. }
  25. ]
  26. }
  27. }
  28. }
  29. }
  30. }
  31. )
  32. puts response

Js

  1. const response = await client.search({
  2. index: "place",
  3. pretty: "true",
  4. suggest: {
  5. place_suggestion: {
  6. prefix: "tim",
  7. completion: {
  8. field: "suggest",
  9. size: 10,
  10. contexts: {
  11. location: [
  12. {
  13. lat: 43.6624803,
  14. lon: -79.3863353,
  15. precision: 2,
  16. },
  17. {
  18. context: {
  19. lat: 43.6624803,
  20. lon: -79.3863353,
  21. },
  22. boost: 2,
  23. },
  24. ],
  25. },
  26. },
  27. },
  28. },
  29. });
  30. console.log(response);

Console

  1. POST place/_search?pretty
  2. {
  3. "suggest": {
  4. "place_suggestion": {
  5. "prefix": "tim",
  6. "completion": {
  7. "field": "suggest",
  8. "size": 10,
  9. "contexts": {
  10. "location": [
  11. {
  12. "lat": 43.6624803,
  13. "lon": -79.3863353,
  14. "precision": 2
  15. },
  16. {
  17. "context": {
  18. "lat": 43.6624803,
  19. "lon": -79.3863353
  20. },
  21. "boost": 2
  22. }
  23. ]
  24. }
  25. }
  26. }
  27. }
  28. }
コンテキストクエリは、ジオロケーションが (43.662, -79.380) のジオハッシュによって表される領域に該当する提案をフィルタリングし、デフォルトの精度 6(43.6624803, -79.3863353) のジオハッシュ表現に該当する提案を 2 の係数でブーストします。

提案エントリが複数のコンテキストに一致する場合、最終スコアは一致するコンテキストの中で生成された最大スコアとして計算されます。

コンテキスト値を受け入れることに加えて、コンテキストクエリは複数のコンテキスト条項で構成されることができます。geo コンテキスト条項に対してサポートされている以下のパラメータ:


| | |
| —- | —- |
| context | フィルタリングまたは提案をブーストするためのジオポイントオブジェクトまたはジオハッシュ文字列。これは必須です。 |
| boost | 提案のスコアをブーストする係数。

スコアはブーストと提案の重みを掛け算して計算され、デフォルトは 1 |
| precision | クエリジオポイントをエンコードするためのジオハッシュの精度。

これは距離値(5m10km など)または生のジオハッシュ精度(1..12)として指定できます。

デフォルトはインデックス時の精度レベルです。 |
| neighbours | 隣接するジオハッシュを考慮する精度値の配列を受け入れます。

精度値は距離値(5m10km など)または生のジオハッシュ精度(1..12)であることができます。デフォルトはインデックス時の精度レベルの隣接を生成します。 |

精度フィールドは距離一致をもたらしません。10km のような距離値を指定することは、そのサイズのタイルを表すジオハッシュ精度値をもたらすだけです。精度は、補完一致のために検索ジオポイントをジオハッシュタイルにエンコードするために使用されます。この結果、タイルの外にあるポイントは、検索ポイントに非常に近くても一致しません。精度を下げるか、距離を増やすことで、これが発生するリスクを減らすことができますが、完全に排除することはできません。

Returning the type of the suggester

時には、サジェスターの結果を解析するために、サジェスターの正確なタイプを知る必要があります。typed_keys パラメータを使用して、応答内でサジェスターの名前を変更し、そのタイプによってプレフィックスを付けることができます。

以下の例では、2つのサジェスター termphrase を考慮します:

Python

  1. resp = client.search(
  2. typed_keys=True,
  3. suggest={
  4. "text": "some test mssage",
  5. "my-first-suggester": {
  6. "term": {
  7. "field": "message"
  8. }
  9. },
  10. "my-second-suggester": {
  11. "phrase": {
  12. "field": "message"
  13. }
  14. }
  15. },
  16. )
  17. print(resp)

Ruby

  1. response = client.search(
  2. typed_keys: true,
  3. body: {
  4. suggest: {
  5. text: 'some test mssage',
  6. "my-first-suggester": {
  7. term: {
  8. field: 'message'
  9. }
  10. },
  11. "my-second-suggester": {
  12. phrase: {
  13. field: 'message'
  14. }
  15. }
  16. }
  17. }
  18. )
  19. puts response

Js

  1. const response = await client.search({
  2. typed_keys: "true",
  3. suggest: {
  4. text: "some test mssage",
  5. "my-first-suggester": {
  6. term: {
  7. field: "message",
  8. },
  9. },
  10. "my-second-suggester": {
  11. phrase: {
  12. field: "message",
  13. },
  14. },
  15. },
  16. });
  17. console.log(response);

Console

  1. POST _search?typed_keys
  2. {
  3. "suggest": {
  4. "text" : "some test mssage",
  5. "my-first-suggester" : {
  6. "term" : {
  7. "field" : "message"
  8. }
  9. },
  10. "my-second-suggester" : {
  11. "phrase" : {
  12. "field" : "message"
  13. }
  14. }
  15. }
  16. }

応答では、サジェスターの名前はそれぞれ term#my-first-suggesterphrase#my-second-suggester に変更され、各提案のタイプを反映します:

Console-Result

  1. {
  2. "suggest": {
  3. "term#my-first-suggester": [
  4. {
  5. "text": "some",
  6. "offset": 0,
  7. "length": 4,
  8. "options": []
  9. },
  10. {
  11. "text": "test",
  12. "offset": 5,
  13. "length": 4,
  14. "options": []
  15. },
  16. {
  17. "text": "mssage",
  18. "offset": 10,
  19. "length": 6,
  20. "options": [
  21. {
  22. "text": "message",
  23. "score": 0.8333333,
  24. "freq": 4
  25. }
  26. ]
  27. }
  28. ],
  29. "phrase#my-second-suggester": [
  30. {
  31. "text": "some test mssage",
  32. "offset": 0,
  33. "length": 16,
  34. "options": [
  35. {
  36. "text": "some test message",
  37. "score": 0.030227963
  38. }
  39. ]
  40. }
  41. ]
  42. },
  43. ...
  44. }
名前 my-first-suggester は現在 term プレフィックスを含んでいます。
名前 my-second-suggester は現在 phrase プレフィックスを含んでいます。