パーコレートクエリ

percolate クエリは、インデックスに保存されたクエリと一致させるために使用できます。 percolate クエリ自体には、保存されたクエリと一致させるために使用されるドキュメントが含まれています。

サンプル使用法

簡単な例を提供するために、このドキュメントでは、my-index-000001 インデックスをパーコレートクエリとドキュメントの両方に使用します。この設定は、登録されたパーコレートクエリが少数の場合にうまく機能します。より多くの使用がある場合は、クエリとドキュメントを別々のインデックスに保存することをお勧めします。詳細については、内部の動作を参照してください。

2つのフィールドを持つインデックスを作成します:

Python

  1. resp = client.indices.create(
  2. index="my-index-000001",
  3. mappings={
  4. "properties": {
  5. "message": {
  6. "type": "text"
  7. },
  8. "query": {
  9. "type": "percolator"
  10. }
  11. }
  12. },
  13. )
  14. print(resp)

Ruby

  1. response = client.indices.create(
  2. index: 'my-index-000001',
  3. body: {
  4. mappings: {
  5. properties: {
  6. message: {
  7. type: 'text'
  8. },
  9. query: {
  10. type: 'percolator'
  11. }
  12. }
  13. }
  14. }
  15. )
  16. puts response

Js

  1. const response = await client.indices.create({
  2. index: "my-index-000001",
  3. mappings: {
  4. properties: {
  5. message: {
  6. type: "text",
  7. },
  8. query: {
  9. type: "percolator",
  10. },
  11. },
  12. },
  13. });
  14. console.log(response);

コンソール

  1. PUT /my-index-000001
  2. {
  3. "mappings": {
  4. "properties": {
  5. "message": {
  6. "type": "text"
  7. },
  8. "query": {
  9. "type": "percolator"
  10. }
  11. }
  12. }
  13. }

message フィールドは、percolator クエリで定義されたドキュメントを一時インデックスにインデックス化する前に前処理するために使用されるフィールドです。

query フィールドは、クエリドキュメントのインデックス化に使用されます。これは、実際の Elasticsearch クエリを表す JSON オブジェクトを保持します。query フィールドは、パーコレータフィールドタイプを使用するように構成されています。このフィールドタイプは、クエリ DSL を理解し、percolate クエリで定義されたドキュメントと一致させるために後で使用できるようにクエリを保存します。

パーコレータにクエリを登録します:

Python

  1. resp = client.index(
  2. index="my-index-000001",
  3. id="1",
  4. refresh=True,
  5. document={
  6. "query": {
  7. "match": {
  8. "message": "bonsai tree"
  9. }
  10. }
  11. },
  12. )
  13. print(resp)

Ruby

  1. response = client.index(
  2. index: 'my-index-000001',
  3. id: 1,
  4. refresh: true,
  5. body: {
  6. query: {
  7. match: {
  8. message: 'bonsai tree'
  9. }
  10. }
  11. }
  12. )
  13. puts response

Js

  1. const response = await client.index({
  2. index: "my-index-000001",
  3. id: 1,
  4. refresh: "true",
  5. document: {
  6. query: {
  7. match: {
  8. message: "bonsai tree",
  9. },
  10. },
  11. },
  12. });
  13. console.log(response);

コンソール

  1. PUT /my-index-000001/_doc/1?refresh
  2. {
  3. "query": {
  4. "match": {
  5. "message": "bonsai tree"
  6. }
  7. }
  8. }

登録されたパーコレータクエリにドキュメントを一致させます:

Python

  1. resp = client.search(
  2. index="my-index-000001",
  3. query={
  4. "percolate": {
  5. "field": "query",
  6. "document": {
  7. "message": "A new bonsai tree in the office"
  8. }
  9. }
  10. },
  11. )
  12. print(resp)

Js

  1. const response = await client.search({
  2. index: "my-index-000001",
  3. query: {
  4. percolate: {
  5. field: "query",
  6. document: {
  7. message: "A new bonsai tree in the office",
  8. },
  9. },
  10. },
  11. });
  12. console.log(response);

コンソール

  1. GET /my-index-000001/_search
  2. {
  3. "query": {
  4. "percolate": {
  5. "field": "query",
  6. "document": {
  7. "message": "A new bonsai tree in the office"
  8. }
  9. }
  10. }
  11. }

上記のリクエストは、次のレスポンスを生成します:

コンソール-結果

  1. {
  2. "took": 13,
  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": 1,
  13. "relation": "eq"
  14. },
  15. "max_score": 0.26152915,
  16. "hits": [
  17. {
  18. "_index": "my-index-000001",
  19. "_id": "1",
  20. "_score": 0.26152915,
  21. "_source": {
  22. "query": {
  23. "match": {
  24. "message": "bonsai tree"
  25. }
  26. }
  27. },
  28. "fields" : {
  29. "_percolator_document_slot" : [0]
  30. }
  31. }
  32. ]
  33. }
  34. }
ID 1 のクエリが私たちのドキュメントと一致します。
_percolator_document_slot フィールドは、このクエリと一致したドキュメントを示します。
複数のドキュメントを同時にパーコレートする際に便利です。

パラメータ

ドキュメントをパーコレートする際に必要なパラメータは次のとおりです:

field インデックスされたクエリを保持する percolator タイプのフィールド。これは必須のパラメータです。
name 複数の percolate クエリが指定された場合に _percolator_document_slot フィールドに使用されるサフィックス。
これはオプションのパラメータです。
document パーコレートされるドキュメントのソース。
documents document パラメータのように、ただし JSON 配列を介して複数のドキュメントを受け入れます。
document_type パーコレートされるドキュメントのタイプ/マッピング。このパラメータは非推奨で、Elasticsearch 8.0 で削除されます。

パーコレートされるドキュメントのソースを指定する代わりに、すでに保存されたドキュメントからソースを取得することもできます。percolate クエリは、そのドキュメントを取得するために内部的に get リクエストを実行します。

その場合、document パラメータは次のパラメータに置き換えることができます:


| | |
| —- | —- |
| index | ドキュメントが存在するインデックス。これは必須のパラメータです。 |
| type | 取得するドキュメントのタイプ。このパラメータは非推奨で、Elasticsearch 8.0 で削除されます。 |
| id | 取得するドキュメントの ID。これは必須のパラメータです。 |
| routing | オプションで、パーコレートするドキュメントを取得するために使用されるルーティング。 |
| preference | オプションで、パーコレートするドキュメントを取得するために使用される優先度。 |
| version | オプションで、取得されるドキュメントの期待されるバージョン。 |

フィルターコンテキストでのパーコレート

スコアに興味がない場合は、bool クエリのフィルター句または constant_score クエリ内にパーコレータクエリをラップすることで、より良いパフォーマンスが期待できます。

Python

  1. resp = client.search(
  2. index="my-index-000001",
  3. query={
  4. "constant_score": {
  5. "filter": {
  6. "percolate": {
  7. "field": "query",
  8. "document": {
  9. "message": "A new bonsai tree in the office"
  10. }
  11. }
  12. }
  13. }
  14. },
  15. )
  16. print(resp)

Js

  1. const response = await client.search({
  2. index: "my-index-000001",
  3. query: {
  4. constant_score: {
  5. filter: {
  6. percolate: {
  7. field: "query",
  8. document: {
  9. message: "A new bonsai tree in the office",
  10. },
  11. },
  12. },
  13. },
  14. },
  15. });
  16. console.log(response);

コンソール

  1. GET /my-index-000001/_search
  2. {
  3. "query": {
  4. "constant_score": {
  5. "filter": {
  6. "percolate": {
  7. "field": "query",
  8. "document": {
  9. "message": "A new bonsai tree in the office"
  10. }
  11. }
  12. }
  13. }
  14. }
  15. }

インデックス時に、パーコレータクエリから用語が抽出され、パーコレータはしばしば抽出された用語を見てクエリが一致するかどうかを判断できます。ただし、スコアを計算するには、一致する各クエリをデシリアライズし、パーコレートされたドキュメントに対して実行する必要があり、これははるかに高価な操作です。したがって、スコアの計算が必要ない場合は、percolate クエリを constant_score クエリまたは bool クエリのフィルター句でラップする必要があります。

percolate クエリは、クエリキャッシュによってキャッシュされることはありません。

複数のドキュメントをパーコレート

percolate クエリは、インデックスされたパーコレータクエリと同時に複数のドキュメントと一致させることができます。単一のリクエストで複数のドキュメントをパーコレートすることで、クエリを複数回解析して一致させる必要がなくなるため、パフォーマンスが向上します。

各一致したパーコレータクエリと共に返される _percolator_document_slot フィールドは、複数のドキュメントを同時にパーコレートする際に重要です。これは、特定のパーコレータクエリと一致したドキュメントを示します。数字は、documents 配列内のスロットと相関しています。

Python

  1. resp = client.search(
  2. index="my-index-000001",
  3. query={
  4. "percolate": {
  5. "field": "query",
  6. "documents": [
  7. {
  8. "message": "bonsai tree"
  9. },
  10. {
  11. "message": "new tree"
  12. },
  13. {
  14. "message": "the office"
  15. },
  16. {
  17. "message": "office tree"
  18. }
  19. ]
  20. }
  21. },
  22. )
  23. print(resp)

Js

  1. const response = await client.search({
  2. index: "my-index-000001",
  3. query: {
  4. percolate: {
  5. field: "query",
  6. documents: [
  7. {
  8. message: "bonsai tree",
  9. },
  10. {
  11. message: "new tree",
  12. },
  13. {
  14. message: "the office",
  15. },
  16. {
  17. message: "office tree",
  18. },
  19. ],
  20. },
  21. },
  22. });
  23. console.log(response);

コンソール

  1. GET /my-index-000001/_search
  2. {
  3. "query": {
  4. "percolate": {
  5. "field": "query",
  6. "documents": [
  7. {
  8. "message": "bonsai tree"
  9. },
  10. {
  11. "message": "new tree"
  12. },
  13. {
  14. "message": "the office"
  15. },
  16. {
  17. "message": "office tree"
  18. }
  19. ]
  20. }
  21. }
  22. }
ドキュメント配列には、同時にパーコレートされる4つのドキュメントが含まれています。

コンソール-結果

  1. {
  2. "took": 13,
  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": 1,
  13. "relation": "eq"
  14. },
  15. "max_score": 0.7093853,
  16. "hits": [
  17. {
  18. "_index": "my-index-000001",
  19. "_id": "1",
  20. "_score": 0.7093853,
  21. "_source": {
  22. "query": {
  23. "match": {
  24. "message": "bonsai tree"
  25. }
  26. }
  27. },
  28. "fields" : {
  29. "_percolator_document_slot" : [0, 1, 3]
  30. }
  31. }
  32. ]
  33. }
  34. }
_percolator_document_slot は、percolate クエリで指定された最初、2番目、最後のドキュメントがこのクエリと一致していることを示します。

既存のドキュメントをパーコレート

新しくインデックスされたドキュメントをパーコレートするには、percolate クエリを使用できます。インデックスリクエストからのレスポンスに基づいて、_id およびその他のメタ情報を使用して、新しく追加されたドキュメントを即座にパーコレートできます。

前の例に基づいています。

パーコレートしたいドキュメントをインデックスします:

Python

  1. resp = client.index(
  2. index="my-index-000001",
  3. id="2",
  4. document={
  5. "message": "A new bonsai tree in the office"
  6. },
  7. )
  8. print(resp)

Ruby

  1. response = client.index(
  2. index: 'my-index-000001',
  3. id: 2,
  4. body: {
  5. message: 'A new bonsai tree in the office'
  6. }
  7. )
  8. puts response

Js

  1. const response = await client.index({
  2. index: "my-index-000001",
  3. id: 2,
  4. document: {
  5. message: "A new bonsai tree in the office",
  6. },
  7. });
  8. console.log(response);

コンソール

  1. PUT /my-index-000001/_doc/2
  2. {
  3. "message" : "A new bonsai tree in the office"
  4. }

インデックスレスポンス:

コンソール-結果

  1. {
  2. "_index": "my-index-000001",
  3. "_id": "2",
  4. "_version": 1,
  5. "_shards": {
  6. "total": 2,
  7. "successful": 1,
  8. "failed": 0
  9. },
  10. "result": "created",
  11. "_seq_no" : 1,
  12. "_primary_term" : 1
  13. }

既存のドキュメントをパーコレートし、インデックスレスポンスを基に新しい検索リクエストを構築します:

Python

  1. resp = client.search(
  2. index="my-index-000001",
  3. query={
  4. "percolate": {
  5. "field": "query",
  6. "index": "my-index-000001",
  7. "id": "2",
  8. "version": 1
  9. }
  10. },
  11. )
  12. print(resp)

Js

  1. const response = await client.search({
  2. index: "my-index-000001",
  3. query: {
  4. percolate: {
  5. field: "query",
  6. index: "my-index-000001",
  7. id: "2",
  8. version: 1,
  9. },
  10. },
  11. });
  12. console.log(response);

コンソール

  1. GET /my-index-000001/_search
  2. {
  3. "query": {
  4. "percolate": {
  5. "field": "query",
  6. "index": "my-index-000001",
  7. "id": "2",
  8. "version": 1
  9. }
  10. }
  11. }
バージョンはオプションですが、特定のケースでは便利です。インデックスしたばかりのドキュメントをパーコレートしようとしていることを確認できます。インデックス後に変更が行われる可能性があり、その場合、検索リクエストはバージョンの競合エラーで失敗します。

返された検索レスポンスは、前の例と同じです。

パーコレートクエリとハイライト

percolate クエリは、ハイライトに関して特別な方法で処理されます。クエリのヒットは、percolate クエリで提供されるドキュメントをハイライトするために使用されます。一方、通常のハイライトでは、検索リクエストのクエリがヒットをハイライトするために使用されます。

この例は、最初の例のマッピングに基づいています。

クエリを保存します:

Python

  1. resp = client.index(
  2. index="my-index-000001",
  3. id="3",
  4. refresh=True,
  5. document={
  6. "query": {
  7. "match": {
  8. "message": "brown fox"
  9. }
  10. }
  11. },
  12. )
  13. print(resp)

Ruby

  1. response = client.index(
  2. index: 'my-index-000001',
  3. id: 3,
  4. refresh: true,
  5. body: {
  6. query: {
  7. match: {
  8. message: 'brown fox'
  9. }
  10. }
  11. }
  12. )
  13. puts response

Js

  1. const response = await client.index({
  2. index: "my-index-000001",
  3. id: 3,
  4. refresh: "true",
  5. document: {
  6. query: {
  7. match: {
  8. message: "brown fox",
  9. },
  10. },
  11. },
  12. });
  13. console.log(response);

コンソール

  1. PUT /my-index-000001/_doc/3?refresh
  2. {
  3. "query": {
  4. "match": {
  5. "message": "brown fox"
  6. }
  7. }
  8. }

別のクエリを保存します:

Python

  1. resp = client.index(
  2. index="my-index-000001",
  3. id="4",
  4. refresh=True,
  5. document={
  6. "query": {
  7. "match": {
  8. "message": "lazy dog"
  9. }
  10. }
  11. },
  12. )
  13. print(resp)

Ruby

  1. response = client.index(
  2. index: 'my-index-000001',
  3. id: 4,
  4. refresh: true,
  5. body: {
  6. query: {
  7. match: {
  8. message: 'lazy dog'
  9. }
  10. }
  11. }
  12. )
  13. puts response

Js

  1. const response = await client.index({
  2. index: "my-index-000001",
  3. id: 4,
  4. refresh: "true",
  5. document: {
  6. query: {
  7. match: {
  8. message: "lazy dog",
  9. },
  10. },
  11. },
  12. });
  13. console.log(response);

コンソール

  1. PUT /my-index-000001/_doc/4?refresh
  2. {
  3. "query": {
  4. "match": {
  5. "message": "lazy dog"
  6. }
  7. }
  8. }

percolate クエリとハイライトを有効にした検索リクエストを実行します:

Python

  1. resp = client.search(
  2. index="my-index-000001",
  3. query={
  4. "percolate": {
  5. "field": "query",
  6. "document": {
  7. "message": "The quick brown fox jumps over the lazy dog"
  8. }
  9. }
  10. },
  11. highlight={
  12. "fields": {
  13. "message": {}
  14. }
  15. },
  16. )
  17. print(resp)

Js

  1. const response = await client.search({
  2. index: "my-index-000001",
  3. query: {
  4. percolate: {
  5. field: "query",
  6. document: {
  7. message: "The quick brown fox jumps over the lazy dog",
  8. },
  9. },
  10. },
  11. highlight: {
  12. fields: {
  13. message: {},
  14. },
  15. },
  16. });
  17. console.log(response);

コンソール

  1. GET /my-index-000001/_search
  2. {
  3. "query": {
  4. "percolate": {
  5. "field": "query",
  6. "document": {
  7. "message": "The quick brown fox jumps over the lazy dog"
  8. }
  9. }
  10. },
  11. "highlight": {
  12. "fields": {
  13. "message": {}
  14. }
  15. }
  16. }

次のレスポンスが得られます。

コンソール-結果

  1. {
  2. "took": 7,
  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": 2,
  13. "relation": "eq"
  14. },
  15. "max_score": 0.26152915,
  16. "hits": [
  17. {
  18. "_index": "my-index-000001",
  19. "_id": "3",
  20. "_score": 0.26152915,
  21. "_source": {
  22. "query": {
  23. "match": {
  24. "message": "brown fox"
  25. }
  26. }
  27. },
  28. "highlight": {
  29. "message": [
  30. "The quick <em>brown</em> <em>fox</em> jumps over the lazy dog"
  31. ]
  32. },
  33. "fields" : {
  34. "_percolator_document_slot" : [0]
  35. }
  36. },
  37. {
  38. "_index": "my-index-000001",
  39. "_id": "4",
  40. "_score": 0.26152915,
  41. "_source": {
  42. "query": {
  43. "match": {
  44. "message": "lazy dog"
  45. }
  46. }
  47. },
  48. "highlight": {
  49. "message": [
  50. "The quick brown fox jumps over the <em>lazy</em> <em>dog</em>"
  51. ]
  52. },
  53. "fields" : {
  54. "_percolator_document_slot" : [0]
  55. }
  56. }
  57. ]
  58. }
  59. }
各クエリの用語がドキュメント内でハイライトされています。

検索リクエストのクエリがパーコレータのヒットをハイライトするのではなく、パーコレータクエリが percolate クエリで定義されたドキュメントをハイライトしています。

以下のリクエストのように、複数のドキュメントを同時にパーコレートする場合、ハイライトレスポンスは異なります:

Python

  1. resp = client.search(
  2. index="my-index-000001",
  3. query={
  4. "percolate": {
  5. "field": "query",
  6. "documents": [
  7. {
  8. "message": "bonsai tree"
  9. },
  10. {
  11. "message": "new tree"
  12. },
  13. {
  14. "message": "the office"
  15. },
  16. {
  17. "message": "office tree"
  18. }
  19. ]
  20. }
  21. },
  22. highlight={
  23. "fields": {
  24. "message": {}
  25. }
  26. },
  27. )
  28. print(resp)

Js

  1. const response = await client.search({
  2. index: "my-index-000001",
  3. query: {
  4. percolate: {
  5. field: "query",
  6. documents: [
  7. {
  8. message: "bonsai tree",
  9. },
  10. {
  11. message: "new tree",
  12. },
  13. {
  14. message: "the office",
  15. },
  16. {
  17. message: "office tree",
  18. },
  19. ],
  20. },
  21. },
  22. highlight: {
  23. fields: {
  24. message: {},
  25. },
  26. },
  27. });
  28. console.log(response);

コンソール

  1. GET /my-index-000001/_search
  2. {
  3. "query": {
  4. "percolate": {
  5. "field": "query",
  6. "documents": [
  7. {
  8. "message": "bonsai tree"
  9. },
  10. {
  11. "message": "new tree"
  12. },
  13. {
  14. "message": "the office"
  15. },
  16. {
  17. "message": "office tree"
  18. }
  19. ]
  20. }
  21. },
  22. "highlight": {
  23. "fields": {
  24. "message": {}
  25. }
  26. }
  27. }

少し異なるレスポンス:

コンソール-結果

  1. {
  2. "took": 13,
  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": 1,
  13. "relation": "eq"
  14. },
  15. "max_score": 0.7093853,
  16. "hits": [
  17. {
  18. "_index": "my-index-000001",
  19. "_id": "1",
  20. "_score": 0.7093853,
  21. "_source": {
  22. "query": {
  23. "match": {
  24. "message": "bonsai tree"
  25. }
  26. }
  27. },
  28. "fields" : {
  29. "_percolator_document_slot" : [0, 1, 3]
  30. },
  31. "highlight" : {
  32. "0_message" : [
  33. "<em>bonsai</em> <em>tree</em>"
  34. ],
  35. "3_message" : [
  36. "office <em>tree</em>"
  37. ],
  38. "1_message" : [
  39. "new <em>tree</em>"
  40. ]
  41. }
  42. }
  43. ]
  44. }
  45. }
ハイライトフィールドは、それに属するドキュメントスロットでプレフィックスされています。
どのハイライトフィールドがどのドキュメントに属するかを知るために。

パーコレータクエリ内の名前付きクエリ

保存されたパーコレータクエリが複雑なクエリであり、どのサブクエリがパーコレートされたドキュメントに一致したかを追跡したい場合は、サブクエリの \_name パラメータを使用できます。この場合、レスポンス内の各ヒットには、_percolator_document_slot フィールドと共に、各パーコレートされたドキュメントに一致した _percolator_document_slot_<slotNumber>_matched_queries フィールドが含まれます。

例えば:

Python

  1. resp = client.index(
  2. index="my-index-000001",
  3. id="5",
  4. refresh=True,
  5. document={
  6. "query": {
  7. "bool": {
  8. "should": [
  9. {
  10. "match": {
  11. "message": {
  12. "query": "Japanese art",
  13. "_name": "query1"
  14. }
  15. }
  16. },
  17. {
  18. "match": {
  19. "message": {
  20. "query": "Holand culture",
  21. "_name": "query2"
  22. }
  23. }
  24. }
  25. ]
  26. }
  27. }
  28. },
  29. )
  30. print(resp)

Ruby

  1. response = client.index(
  2. index: 'my-index-000001',
  3. id: 5,
  4. refresh: true,
  5. body: {
  6. query: {
  7. bool: {
  8. should: [
  9. {
  10. match: {
  11. message: {
  12. query: 'Japanese art',
  13. _name: 'query1'
  14. }
  15. }
  16. },
  17. {
  18. match: {
  19. message: {
  20. query: 'Holand culture',
  21. _name: 'query2'
  22. }
  23. }
  24. }
  25. ]
  26. }
  27. }
  28. }
  29. )
  30. puts response

Js

  1. const response = await client.index({
  2. index: "my-index-000001",
  3. id: 5,
  4. refresh: "true",
  5. document: {
  6. query: {
  7. bool: {
  8. should: [
  9. {
  10. match: {
  11. message: {
  12. query: "Japanese art",
  13. _name: "query1",
  14. },
  15. },
  16. },
  17. {
  18. match: {
  19. message: {
  20. query: "Holand culture",
  21. _name: "query2",
  22. },
  23. },
  24. },
  25. ],
  26. },
  27. },
  28. },
  29. });
  30. console.log(response);

コンソール

  1. PUT /my-index-000001/_doc/5?refresh
  2. {
  3. "query": {
  4. "bool": {
  5. "should": [
  6. {
  7. "match": {
  8. "message": {
  9. "query": "Japanese art",
  10. "_name": "query1"
  11. }
  12. }
  13. },
  14. {
  15. "match": {
  16. "message": {
  17. "query": "Holand culture",
  18. "_name": "query2"
  19. }
  20. }
  21. }
  22. ]
  23. }
  24. }
  25. }

Python

  1. resp = client.search(
  2. index="my-index-000001",
  3. query={
  4. "percolate": {
  5. "field": "query",
  6. "documents": [
  7. {
  8. "message": "Japanse art"
  9. },
  10. {
  11. "message": "Holand culture"
  12. },
  13. {
  14. "message": "Japanese art and Holand culture"
  15. },
  16. {
  17. "message": "no-match"
  18. }
  19. ]
  20. }
  21. },
  22. )
  23. print(resp)

Js

  1. const response = await client.search({
  2. index: "my-index-000001",
  3. query: {
  4. percolate: {
  5. field: "query",
  6. documents: [
  7. {
  8. message: "Japanse art",
  9. },
  10. {
  11. message: "Holand culture",
  12. },
  13. {
  14. message: "Japanese art and Holand culture",
  15. },
  16. {
  17. message: "no-match",
  18. },
  19. ],
  20. },
  21. },
  22. });
  23. console.log(response);

コンソール

  1. GET /my-index-000001/_search
  2. {
  3. "query": {
  4. "percolate": {
  5. "field": "query",
  6. "documents": [
  7. {
  8. "message": "Japanse art"
  9. },
  10. {
  11. "message": "Holand culture"
  12. },
  13. {
  14. "message": "Japanese art and Holand culture"
  15. },
  16. {
  17. "message": "no-match"
  18. }
  19. ]
  20. }
  21. }
  22. }

コンソール-結果

  1. {
  2. "took": 55,
  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": 1,
  13. "relation": "eq"
  14. },
  15. "max_score": 1.1181908,
  16. "hits": [
  17. {
  18. "_index": "my-index-000001",
  19. "_id": "5",
  20. "_score": 1.1181908,
  21. "_source": {
  22. "query": {
  23. "bool": {
  24. "should": [
  25. {
  26. "match": {
  27. "message": {
  28. "query": "Japanese art",
  29. "_name": "query1"
  30. }
  31. }
  32. },
  33. {
  34. "match": {
  35. "message": {
  36. "query": "Holand culture",
  37. "_name": "query2"
  38. }
  39. }
  40. }
  41. ]
  42. }
  43. }
  44. },
  45. "fields" : {
  46. "_percolator_document_slot" : [0, 1, 2],
  47. "_percolator_document_slot_0_matched_queries" : ["query1"],
  48. "_percolator_document_slot_1_matched_queries" : ["query2"],
  49. "_percolator_document_slot_2_matched_queries" : ["query1", "query2"]
  50. }
  51. }
  52. ]
  53. }
  54. }
最初のドキュメントは最初のサブクエリのみに一致しました。
2番目のドキュメントは2番目のサブクエリのみに一致しました。
3番目のドキュメントは両方のサブクエリに一致しました。

複数のパーコレートクエリを指定

単一の検索リクエストで複数の percolate クエリを指定することが可能です:

Python

  1. resp = client.search(
  2. index="my-index-000001",
  3. query={
  4. "bool": {
  5. "should": [
  6. {
  7. "percolate": {
  8. "field": "query",
  9. "document": {
  10. "message": "bonsai tree"
  11. },
  12. "name": "query1"
  13. }
  14. },
  15. {
  16. "percolate": {
  17. "field": "query",
  18. "document": {
  19. "message": "tulip flower"
  20. },
  21. "name": "query2"
  22. }
  23. }
  24. ]
  25. }
  26. },
  27. )
  28. print(resp)

Js

  1. const response = await client.search({
  2. index: "my-index-000001",
  3. query: {
  4. bool: {
  5. should: [
  6. {
  7. percolate: {
  8. field: "query",
  9. document: {
  10. message: "bonsai tree",
  11. },
  12. name: "query1",
  13. },
  14. },
  15. {
  16. percolate: {
  17. field: "query",
  18. document: {
  19. message: "tulip flower",
  20. },
  21. name: "query2",
  22. },
  23. },
  24. ],
  25. },
  26. },
  27. });
  28. console.log(response);

コンソール

  1. GET /my-index-000001/_search
  2. {
  3. "query": {
  4. "bool": {
  5. "should": [
  6. {
  7. "percolate": {
  8. "field": "query",
  9. "document": {
  10. "message": "bonsai tree"
  11. },
  12. "name": "query1"
  13. }
  14. },
  15. {
  16. "percolate": {
  17. "field": "query",
  18. "document": {
  19. "message": "tulip flower"
  20. },
  21. "name": "query2"
  22. }
  23. }
  24. ]
  25. }
  26. }
  27. }
name パラメータは、どのパーコレータドキュメントスロットがどの percolate クエリに属するかを識別するために使用されます。

_percolator_document_slot フィールド名は、_name パラメータで指定されたものでサフィックスされます。それが指定されていない場合、field パラメータが使用され、これにより曖昧さが生じます。

上記の検索リクエストは、次のようなレスポンスを返します:

コンソール-結果

  1. {
  2. "took": 13,
  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": 1,
  13. "relation": "eq"
  14. },
  15. "max_score": 0.26152915,
  16. "hits": [
  17. {
  18. "_index": "my-index-000001",
  19. "_id": "1",
  20. "_score": 0.26152915,
  21. "_source": {
  22. "query": {
  23. "match": {
  24. "message": "bonsai tree"
  25. }
  26. }
  27. },
  28. "fields" : {
  29. "_percolator_document_slot_query1" : [0]
  30. }
  31. }
  32. ]
  33. }
  34. }
_percolator_document_slot_query1 パーコレータスロットフィールドは、これらの一致したスロットが percolate クエリの _name パラメータが query1 に設定されていることを示します。

内部の動作

パーコレータフィールドタイプ](/read/elasticsearch-8-15/43c8aef30c6f9416.md) マッピングが構成されたインデックスにドキュメントをインデックスすると、ドキュメントのクエリ部分が解析され、Lucene クエリに変換され、Lucene インデックスに保存されます。クエリのバイナリ表現が保存されますが、クエリの用語も分析され、インデックスフィールドに保存されます。

検索時に、リクエストで指定されたドキュメントが Lucene ドキュメントに解析され、メモリ内の一時 Lucene インデックスに保存されます。このメモリ内インデックスは、この1つのドキュメントのみを保持でき、最適化されています。その後、メモリ内インデックスの用語に基づいて、候補のパーコレータクエリを選択する特別なクエリが構築されます。これらのクエリは、実際に一致するかどうかをメモリ内インデックスによって評価されます。

候補のパーコレータクエリの選択は、percolate クエリの実行中の重要なパフォーマンス最適化であり、メモリ内インデックスが評価する必要のある候補一致の数を大幅に減少させることができます。percolate クエリがこれを行える理由は、パーコレータクエリのインデックス時に、クエリ用語が抽出され、パーコレータクエリと共にインデックスされるからです。残念ながら、パーコレータはすべてのクエリから用語を抽出できず(例えば、wildcard または geo_shape クエリ)、その結果、特定のケースではパーコレータが選択最適化を行えないことがあります(例えば、ブールクエリの必須句にサポートされていないクエリが定義されている場合や、サポートされていないクエリがパーコレータドキュメント内の唯一のクエリである場合)。これらのクエリはパーコレータによってマークされ、次の検索を実行することで見つけることができます:

Python

  1. resp = client.search(
  2. query={
  3. "term": {
  4. "query.extraction_result": "failed"
  5. }
  6. },
  7. )
  8. print(resp)

Ruby

  1. response = client.search(
  2. body: {
  3. query: {
  4. term: {
  5. 'query.extraction_result' => 'failed'
  6. }
  7. }
  8. }
  9. )
  10. puts response

Js

  1. const response = await client.search({
  2. query: {
  3. term: {
  4. "query.extraction_result": "failed",
  5. },
  6. },
  7. });
  8. console.log(response);

コンソール

  1. GET /_search
  2. {
  3. "query": {
  4. "term" : {
  5. "query.extraction_result" : "failed"
  6. }
  7. }
  8. }

上記の例は、マッピングに query フィールドが percolator タイプであることを前提としています。

パーコレートの設計を考慮すると、パーコレートクエリとパーコレートされるドキュメントに別々のインデックスを使用することが理にかなっていることが多く、例のように単一のインデックスを使用するのではなく、いくつかの利点があります:

  • パーコレートクエリは、パーコレートされたドキュメントとは異なるフィールドセットを含むため、2つの別々のインデックスを使用することで、フィールドをより密に、効率的に保存できます。
  • パーコレートクエリは、他のクエリと同じようにはスケールしないため、パーコレートのパフォーマンスは、プライマリシャードの数のような異なるインデックス構成を使用することで向上する可能性があります。

ノート

高コストのクエリを許可

search.allow_expensive_queries が false に設定されている場合、パーコレートクエリは実行されません。

カスタム類似性の使用

パーコレートクエリは、設定された カスタム類似性 を尊重しません。常にデフォルトの Lucene 類似性を使用します。