バケットソート集約

親パイプライン集約で、親のマルチバケット集約のバケットをソートします。ゼロ個以上のソートフィールドを指定し、対応するソート順序を設定できます。各バケットは、その _key_count またはそのサブ集約に基づいてソートされる場合があります。さらに、from および size パラメータを設定して、結果バケットを切り捨てることができます。

bucket_sort 集約は、すべての他の非パイプライン集約の後に実行されるため、すべてのパイプライン集約と同様です。これは、ソートが親集約からすでに返されたバケットにのみ適用されることを意味します。たとえば、親集約が terms で、その size10 に設定されている場合、bucket_sort は返された10の用語バケットの上でのみソートされます。

構文

bucket_sort 集約は、単独で次のようになります:

Js

  1. {
  2. "bucket_sort": {
  3. "sort": [
  4. { "sort_field_1": { "order": "asc" } },
  5. { "sort_field_2": { "order": "desc" } },
  6. "sort_field_3"
  7. ],
  8. "from": 1,
  9. "size": 3
  10. }
  11. }
ここで、sort_field_1 は主なソートに使用される変数へのバケットパスであり、その順序は昇順です。


表 56. bucket_sort パラメータ


| パラメータ名 | 説明 | 必須 | デフォルト値 |
| :— | :— | :— | :— |
| sort | ソートするフィールドのリスト。詳細については sort を参照してください。 | オプション | |
| from | 設定値より前の位置にあるバケットは切り捨てられます。 | オプション | 0 |
| size | 返すバケットの数。親集約のすべてのバケットがデフォルトです。 | オプション | |
| gap_policy | データにギャップが見つかった場合に適用するポリシー(詳細については データのギャップの処理 を参照) | オプション | skip |

次のスニペットは、降順で合計売上が最も高い3か月に対応するバケットを返します:

Python

  1. resp = client.search(
  2. index="sales",
  3. size=0,
  4. aggs={
  5. "sales_per_month": {
  6. "date_histogram": {
  7. "field": "date",
  8. "calendar_interval": "month"
  9. },
  10. "aggs": {
  11. "total_sales": {
  12. "sum": {
  13. "field": "price"
  14. }
  15. },
  16. "sales_bucket_sort": {
  17. "bucket_sort": {
  18. "sort": [
  19. {
  20. "total_sales": {
  21. "order": "desc"
  22. }
  23. }
  24. ],
  25. "size": 3
  26. }
  27. }
  28. }
  29. }
  30. },
  31. )
  32. print(resp)

Ruby

  1. response = client.search(
  2. index: 'sales',
  3. body: {
  4. size: 0,
  5. aggregations: {
  6. sales_per_month: {
  7. date_histogram: {
  8. field: 'date',
  9. calendar_interval: 'month'
  10. },
  11. aggregations: {
  12. total_sales: {
  13. sum: {
  14. field: 'price'
  15. }
  16. },
  17. sales_bucket_sort: {
  18. bucket_sort: {
  19. sort: [
  20. {
  21. total_sales: {
  22. order: 'desc'
  23. }
  24. }
  25. ],
  26. size: 3
  27. }
  28. }
  29. }
  30. }
  31. }
  32. }
  33. )
  34. puts response

Js

  1. const response = await client.search({
  2. index: "sales",
  3. size: 0,
  4. aggs: {
  5. sales_per_month: {
  6. date_histogram: {
  7. field: "date",
  8. calendar_interval: "month",
  9. },
  10. aggs: {
  11. total_sales: {
  12. sum: {
  13. field: "price",
  14. },
  15. },
  16. sales_bucket_sort: {
  17. bucket_sort: {
  18. sort: [
  19. {
  20. total_sales: {
  21. order: "desc",
  22. },
  23. },
  24. ],
  25. size: 3,
  26. },
  27. },
  28. },
  29. },
  30. },
  31. });
  32. console.log(response);

コンソール

  1. POST /sales/_search
  2. {
  3. "size": 0,
  4. "aggs": {
  5. "sales_per_month": {
  6. "date_histogram": {
  7. "field": "date",
  8. "calendar_interval": "month"
  9. },
  10. "aggs": {
  11. "total_sales": {
  12. "sum": {
  13. "field": "price"
  14. }
  15. },
  16. "sales_bucket_sort": {
  17. "bucket_sort": {
  18. "sort": [
  19. { "total_sales": { "order": "desc" } }
  20. ],
  21. "size": 3
  22. }
  23. }
  24. }
  25. }
  26. }
  27. }
sorttotal_sales の値を降順で使用するように設定されています
size3 に設定されており、total_sales の上位3か月のみが返されます

次のような応答があるかもしれません:

コンソール-結果

  1. {
  2. "took": 82,
  3. "timed_out": false,
  4. "_shards": ...,
  5. "hits": ...,
  6. "aggregations": {
  7. "sales_per_month": {
  8. "buckets": [
  9. {
  10. "key_as_string": "2015/01/01 00:00:00",
  11. "key": 1420070400000,
  12. "doc_count": 3,
  13. "total_sales": {
  14. "value": 550.0
  15. }
  16. },
  17. {
  18. "key_as_string": "2015/03/01 00:00:00",
  19. "key": 1425168000000,
  20. "doc_count": 2,
  21. "total_sales": {
  22. "value": 375.0
  23. }
  24. },
  25. {
  26. "key_as_string": "2015/02/01 00:00:00",
  27. "key": 1422748800000,
  28. "doc_count": 2,
  29. "total_sales": {
  30. "value": 60.0
  31. }
  32. }
  33. ]
  34. }
  35. }
  36. }

ソートなしでの切り捨て

この集約を使用して、ソートを行わずに結果バケットを切り捨てることも可能です。そのためには、from および/または size パラメータを使用し、sort を指定しないだけです。

次の例は、結果を単純に切り捨てて、2番目のバケットのみを返します:

Python

  1. resp = client.search(
  2. index="sales",
  3. size=0,
  4. aggs={
  5. "sales_per_month": {
  6. "date_histogram": {
  7. "field": "date",
  8. "calendar_interval": "month"
  9. },
  10. "aggs": {
  11. "bucket_truncate": {
  12. "bucket_sort": {
  13. "from": 1,
  14. "size": 1
  15. }
  16. }
  17. }
  18. }
  19. },
  20. )
  21. print(resp)

Ruby

  1. response = client.search(
  2. index: 'sales',
  3. body: {
  4. size: 0,
  5. aggregations: {
  6. sales_per_month: {
  7. date_histogram: {
  8. field: 'date',
  9. calendar_interval: 'month'
  10. },
  11. aggregations: {
  12. bucket_truncate: {
  13. bucket_sort: {
  14. from: 1,
  15. size: 1
  16. }
  17. }
  18. }
  19. }
  20. }
  21. }
  22. )
  23. puts response

Js

  1. const response = await client.search({
  2. index: "sales",
  3. size: 0,
  4. aggs: {
  5. sales_per_month: {
  6. date_histogram: {
  7. field: "date",
  8. calendar_interval: "month",
  9. },
  10. aggs: {
  11. bucket_truncate: {
  12. bucket_sort: {
  13. from: 1,
  14. size: 1,
  15. },
  16. },
  17. },
  18. },
  19. },
  20. });
  21. console.log(response);

コンソール

  1. POST /sales/_search
  2. {
  3. "size": 0,
  4. "aggs": {
  5. "sales_per_month": {
  6. "date_histogram": {
  7. "field": "date",
  8. "calendar_interval": "month"
  9. },
  10. "aggs": {
  11. "bucket_truncate": {
  12. "bucket_sort": {
  13. "from": 1,
  14. "size": 1
  15. }
  16. }
  17. }
  18. }
  19. }
  20. }

応答:

コンソール-結果

  1. {
  2. "took": 11,
  3. "timed_out": false,
  4. "_shards": ...,
  5. "hits": ...,
  6. "aggregations": {
  7. "sales_per_month": {
  8. "buckets": [
  9. {
  10. "key_as_string": "2015/02/01 00:00:00",
  11. "key": 1422748800000,
  12. "doc_count": 2
  13. }
  14. ]
  15. }
  16. }
  17. }