マルチターム集約

ユニークな値のセットごとにバケットが動的に構築されるマルチバケット値ソースに基づく集約です。マルチターム集約は、terms aggregationに非常に似ていますが、ほとんどの場合、ターム集約よりも遅く、より多くのメモリを消費します。したがって、同じフィールドセットが常に使用される場合は、これらのフィールドの結合キーを別のフィールドとしてインデックス化し、このフィールドに対してターム集約を使用する方が効率的です。

マルチターム集約は、ドキュメント数や複合キーに対するメトリック集約でソートし、上位N件の結果を取得する必要がある場合に最も便利です。ソートが必要ない場合、すべての値がネストされたターム集約を使用して取得されることが期待される場合、composite aggregationsはより迅速でメモリ効率の良い解決策となります。

例:

Python

  1. resp = client.search(
  2. index="products",
  3. aggs={
  4. "genres_and_products": {
  5. "multi_terms": {
  6. "terms": [
  7. {
  8. "field": "genre"
  9. },
  10. {
  11. "field": "product"
  12. }
  13. ]
  14. }
  15. }
  16. },
  17. )
  18. print(resp)

Ruby

  1. response = client.search(
  2. index: 'products',
  3. body: {
  4. aggregations: {
  5. genres_and_products: {
  6. multi_terms: {
  7. terms: [
  8. {
  9. field: 'genre'
  10. },
  11. {
  12. field: 'product'
  13. }
  14. ]
  15. }
  16. }
  17. }
  18. }
  19. )
  20. puts response

Js

  1. const response = await client.search({
  2. index: "products",
  3. aggs: {
  4. genres_and_products: {
  5. multi_terms: {
  6. terms: [
  7. {
  8. field: "genre",
  9. },
  10. {
  11. field: "product",
  12. },
  13. ],
  14. },
  15. },
  16. },
  17. });
  18. console.log(response);

コンソール

  1. GET /products/_search
  2. {
  3. "aggs": {
  4. "genres_and_products": {
  5. "multi_terms": {
  6. "terms": [{
  7. "field": "genre"
  8. }, {
  9. "field": "product"
  10. }]
  11. }
  12. }
  13. }
  14. }
multi_terms集約は、同じフィールドタイプで動作することができ、
terms aggregationのほとんどのターム集約パラメータをサポートします。

レスポンス:

コンソール-結果

  1. {
  2. ...
  3. "aggregations" : {
  4. "genres_and_products" : {
  5. "doc_count_error_upper_bound" : 0,
  6. "sum_other_doc_count" : 0,
  7. "buckets" : [
  8. {
  9. "key" : [
  10. "rock",
  11. "Product A"
  12. ],
  13. "key_as_string" : "rock|Product A",<br> "doc_count" : 2<br> },<br> {<br> "key" : [<br> "electronic",<br> "Product B"<br> ],<br> "key_as_string" : "electronic|Product B",<br> "doc_count" : 1<br> },<br> {<br> "key" : [<br> "jazz",<br> "Product B"<br> ],<br> "key_as_string" : "jazz|Product B",<br> "doc_count" : 1<br> },<br> {<br> "key" : [<br> "rock",<br> "Product B"<br> ],<br> "key_as_string" : "rock|Product B",<br> "doc_count" : 1<br> }<br> ]<br> }<br> }<br>}<br>``````<br><br>
  14. | | |
  15. | --- | --- |
  16. | | 各タームのドキュメントカウントに対する誤差の上限、詳細は <br><<search-aggregations-bucket-multi-terms-aggregation-approximate-counts,below>> |
  17. | | ユニークなタームが多数ある場合、Elasticsearchは上位のタームのみを返します。この数は、レスポンスの一部でないすべてのバケットのドキュメントカウントの合計です |
  18. | | 上位バケットのリスト。 |
  19. | | キーは、集約の`````terms`````パラメータの式と同じ順序で並べられた値の配列です |
  20. デフォルトでは、`````multi_terms`````集約は、`````doc_count`````で順序付けられた上位10タームのバケットを返します。このデフォルトの動作は、`````size`````パラメータを設定することで変更できます。
  21. ## 集約パラメータ
  22. 以下のパラメータがサポートされています。これらのパラメータの詳細な説明については、[`````terms aggregation`````](aa21c04ecd5a1ccc.md#search-aggregations-bucket-terms-aggregation-order)を参照してください。
  23. | | |
  24. | --- | --- |
  25. | size | オプション。全体のタームリストから返されるタームバケットの数を定義します。デフォルトは10です。 |
  26. | shard\_size | オプション。要求された`````size`````が高いほど、結果はより正確になりますが、最終結果を計算するのにより高価になります。デフォルトの`````shard_size``````````(size * 1.5 + 10)`````です。 |
  27. | show\_term\_doc\_count\_error | オプション。各タームに基づいてドキュメントカウントの誤差を計算します。デフォルトは`````false`````です。 |
  28. | order | オプション。バケットの順序を指定します。デフォルトはバケットごとのドキュメント数です。バケットタームの値は、同じドキュメントカウントのバケットのためのタイブレイカーとして使用されます。 |
  29. | min\_doc\_count | オプション。バケットに返されるための最小ドキュメント数です。デフォルトは1です。 |
  30. | shard\_min\_doc\_count | オプション。各シャードのバケットに返されるための最小ドキュメント数です。デフォルトは`````min_doc_count`````です。 |
  31. | collect\_mode | オプション。データ収集の戦略を指定します。`````depth_first`````または`````breadth_first`````モードがサポートされています。デフォルトは`````breadth_first`````です。|
  32. ## スクリプト
  33. スクリプトを使用してタームを生成する:
  34. #### Python
  35. ``````python
  36. resp = client.search(
  37. index="products",
  38. runtime_mappings={
  39. "genre.length": {
  40. "type": "long",
  41. "script": "emit(doc['genre'].value.length())"
  42. }
  43. },
  44. aggs={
  45. "genres_and_products": {
  46. "multi_terms": {
  47. "terms": [
  48. {
  49. "field": "genre.length"
  50. },
  51. {
  52. "field": "product"
  53. }
  54. ]
  55. }
  56. }
  57. },
  58. )
  59. print(resp)

Ruby

  1. response = client.search(
  2. index: 'products',
  3. body: {
  4. runtime_mappings: {
  5. 'genre.length' => {
  6. type: 'long',
  7. script: "emit(doc['genre'].value.length())"
  8. }
  9. },
  10. aggregations: {
  11. genres_and_products: {
  12. multi_terms: {
  13. terms: [
  14. {
  15. field: 'genre.length'
  16. },
  17. {
  18. field: 'product'
  19. }
  20. ]
  21. }
  22. }
  23. }
  24. }
  25. )
  26. puts response

Js

  1. const response = await client.search({
  2. index: "products",
  3. runtime_mappings: {
  4. "genre.length": {
  5. type: "long",
  6. script: "emit(doc['genre'].value.length())",
  7. },
  8. },
  9. aggs: {
  10. genres_and_products: {
  11. multi_terms: {
  12. terms: [
  13. {
  14. field: "genre.length",
  15. },
  16. {
  17. field: "product",
  18. },
  19. ],
  20. },
  21. },
  22. },
  23. });
  24. console.log(response);

コンソール

  1. GET /products/_search
  2. {
  3. "runtime_mappings": {
  4. "genre.length": {
  5. "type": "long",
  6. "script": "emit(doc['genre'].value.length())"
  7. }
  8. },
  9. "aggs": {
  10. "genres_and_products": {
  11. "multi_terms": {
  12. "terms": [
  13. {
  14. "field": "genre.length"
  15. },
  16. {
  17. "field": "product"
  18. }
  19. ]
  20. }
  21. }
  22. }
  23. }

レスポンス:

コンソール-結果

  1. {
  2. ...
  3. "aggregations" : {
  4. "genres_and_products" : {
  5. "doc_count_error_upper_bound" : 0,
  6. "sum_other_doc_count" : 0,
  7. "buckets" : [
  8. {
  9. "key" : [
  10. 4,
  11. "Product A"
  12. ],
  13. "key_as_string" : "4|Product A",
  14. "doc_count" : 2
  15. },
  16. {
  17. "key" : [
  18. 4,
  19. "Product B"
  20. ],
  21. "key_as_string" : "4|Product B",
  22. "doc_count" : 2
  23. },
  24. {
  25. "key" : [
  26. 10,
  27. "Product B"
  28. ],
  29. "key_as_string" : "10|Product B",
  30. "doc_count" : 1
  31. }
  32. ]
  33. }
  34. }
  35. }

欠損値

  1. #### Python
  2. ``````python
  3. resp = client.search(
  4. index="products",
  5. aggs={
  6. "genres_and_products": {
  7. "multi_terms": {
  8. "terms": [
  9. {
  10. "field": "genre"
  11. },
  12. {
  13. "field": "product",
  14. "missing": "Product Z"
  15. }
  16. ]
  17. }
  18. }
  19. },
  20. )
  21. print(resp)
  22. `

Ruby

  1. response = client.search(
  2. index: 'products',
  3. body: {
  4. aggregations: {
  5. genres_and_products: {
  6. multi_terms: {
  7. terms: [
  8. {
  9. field: 'genre'
  10. },
  11. {
  12. field: 'product',
  13. missing: 'Product Z'
  14. }
  15. ]
  16. }
  17. }
  18. }
  19. }
  20. )
  21. puts response

Js

  1. const response = await client.search({
  2. index: "products",
  3. aggs: {
  4. genres_and_products: {
  5. multi_terms: {
  6. terms: [
  7. {
  8. field: "genre",
  9. },
  10. {
  11. field: "product",
  12. missing: "Product Z",
  13. },
  14. ],
  15. },
  16. },
  17. },
  18. });
  19. console.log(response);

コンソール

  1. GET /products/_search
  2. {
  3. "aggs": {
  4. "genres_and_products": {
  5. "multi_terms": {
  6. "terms": [
  7. {
  8. "field": "genre"
  9. },
  10. {
  11. "field": "product",
  12. "missing": "Product Z"
  13. }
  14. ]
  15. }
  16. }
  17. }
  18. }

レスポンス:

コンソール-結果

  1. {
  2. ...
  3. "aggregations" : {
  4. "genres_and_products" : {
  5. "doc_count_error_upper_bound" : 0,
  6. "sum_other_doc_count" : 0,
  7. "buckets" : [
  8. {
  9. "key" : [
  10. "rock",
  11. "Product A"
  12. ],
  13. "key_as_string" : "rock|Product A",<br> "doc_count" : 2<br> },<br> {<br> "key" : [<br> "electronic",<br> "Product B"<br> ],<br> "key_as_string" : "electronic|Product B",<br> "doc_count" : 1<br> },<br> {<br> "key" : [<br> "electronic",<br> "Product Z"<br> ],<br> "key_as_string" : "electronic|Product Z",<br> "doc_count" : 1<br> },<br> {<br> "key" : [<br> "jazz",<br> "Product B"<br> ],<br> "key_as_string" : "jazz|Product B",<br> "doc_count" : 1<br> },<br> {<br> "key" : [<br> "rock",<br> "Product B"<br> ],<br> "key_as_string" : "rock|Product B",<br> "doc_count" : 1<br> }<br> ]<br> }<br> }<br>}<br>``````<br><br>
  14. | | |
  15. | --- | --- |
  16. | | `````product`````フィールドに値がないドキュメントは、値が`````Product Z`````であるドキュメントと同じバケットに入ります。 |
  17. ## フィールドタイプの混合
  18. 複数のインデックスで集約する際、集約フィールドのタイプはすべてのインデックスで同じでない場合があります。一部のタイプは互換性があります(`````integer``````````long`````または`````float``````````double`````)が、デシマルと非デシマルの数の混合の場合、ターム集約は非デシマルの数をデシマルの数に昇格させます。これにより、バケット値の精度が失われる可能性があります。
  19. ## サブ集約とソートの例
  20. ほとんどのバケット集約と同様に、`````multi_term`````はサブ集約をサポートし、メトリックサブ集約によってバケットを順序付けます:
  21. #### Python
  22. ``````python
  23. resp = client.search(
  24. index="products",
  25. aggs={
  26. "genres_and_products": {
  27. "multi_terms": {
  28. "terms": [
  29. {
  30. "field": "genre"
  31. },
  32. {
  33. "field": "product"
  34. }
  35. ],
  36. "order": {
  37. "total_quantity": "desc"
  38. }
  39. },
  40. "aggs": {
  41. "total_quantity": {
  42. "sum": {
  43. "field": "quantity"
  44. }
  45. }
  46. }
  47. }
  48. },
  49. )
  50. print(resp)

Ruby

  1. response = client.search(
  2. index: 'products',
  3. body: {
  4. aggregations: {
  5. genres_and_products: {
  6. multi_terms: {
  7. terms: [
  8. {
  9. field: 'genre'
  10. },
  11. {
  12. field: 'product'
  13. }
  14. ],
  15. order: {
  16. total_quantity: 'desc'
  17. }
  18. },
  19. aggregations: {
  20. total_quantity: {
  21. sum: {
  22. field: 'quantity'
  23. }
  24. }
  25. }
  26. }
  27. }
  28. }
  29. )
  30. puts response

Js

  1. const response = await client.search({
  2. index: "products",
  3. aggs: {
  4. genres_and_products: {
  5. multi_terms: {
  6. terms: [
  7. {
  8. field: "genre",
  9. },
  10. {
  11. field: "product",
  12. },
  13. ],
  14. order: {
  15. total_quantity: "desc",
  16. },
  17. },
  18. aggs: {
  19. total_quantity: {
  20. sum: {
  21. field: "quantity",
  22. },
  23. },
  24. },
  25. },
  26. },
  27. });
  28. console.log(response);

コンソール

  1. GET /products/_search
  2. {
  3. "aggs": {
  4. "genres_and_products": {
  5. "multi_terms": {
  6. "terms": [
  7. {
  8. "field": "genre"
  9. },
  10. {
  11. "field": "product"
  12. }
  13. ],
  14. "order": {
  15. "total_quantity": "desc"
  16. }
  17. },
  18. "aggs": {
  19. "total_quantity": {
  20. "sum": {
  21. "field": "quantity"
  22. }
  23. }
  24. }
  25. }
  26. }
  27. }

コンソール-結果

  1. {
  2. ...
  3. "aggregations" : {
  4. "genres_and_products" : {
  5. "doc_count_error_upper_bound" : 0,
  6. "sum_other_doc_count" : 0,
  7. "buckets" : [
  8. {
  9. "key" : [
  10. "jazz",
  11. "Product B"
  12. ],
  13. "key_as_string" : "jazz|Product B",
  14. "doc_count" : 1,
  15. "total_quantity" : {
  16. "value" : 10.0
  17. }
  18. },
  19. {
  20. "key" : [
  21. "rock",
  22. "Product A"
  23. ],
  24. "key_as_string" : "rock|Product A",
  25. "doc_count" : 2,
  26. "total_quantity" : {
  27. "value" : 9.0
  28. }
  29. },
  30. {
  31. "key" : [
  32. "electronic",
  33. "Product B"
  34. ],
  35. "key_as_string" : "electronic|Product B",
  36. "doc_count" : 1,
  37. "total_quantity" : {
  38. "value" : 3.0
  39. }
  40. },
  41. {
  42. "key" : [
  43. "rock",
  44. "Product B"
  45. ],
  46. "key_as_string" : "rock|Product B",
  47. "doc_count" : 1,
  48. "total_quantity" : {
  49. "value" : 1.0
  50. }
  51. }
  52. ]
  53. }
  54. }
  55. }