ElasticSearch - 使用 Bucket Sort 聚合进行桶排序

发布于:2024-12-18 ⋅ 阅读:(84) ⋅ 点赞:(0)

在这里插入图片描述


官方文档

https://www.elastic.co/guide/en/elasticsearch/reference/current/search-aggregations-pipeline-bucket-sort-aggregation.html

在这里插入图片描述


概述

在 Elasticsearch 中,bucket_sort 聚合是一种父管道聚合(Parent Pipeline Aggregation),用于对其父多桶聚合的桶进行排序。可以指定一个或多个排序字段,并根据这些字段对桶进行排序。每个桶可以基于其 _key_count 或其子聚合进行排序。

此外,还可以设置 fromsize 参数,以限制返回的桶的数量。


1. Bucket Sort 聚合概述

bucket_sort 聚合会在所有非管道聚合执行后进行排序。这意味着排序只会应用于从父聚合中返回的桶。例如,如果父聚合是 terms 聚合,并且其 size 设置为 10,那么 bucket_sort 聚合只会对这 10 个返回的 term 桶进行排序。

2. 语法

以下是 bucket_sort 聚合的基础语法:

{
  "bucket_sort": {
    "sort": [
      { "sort_field_1": { "order": "asc" } },   
      { "sort_field_2": { "order": "desc" } },
      "sort_field_3"
    ],
    "from": 1,
    "size": 3
  }
}
  • sort: 这是一个字段列表,用于指定排序的依据。你可以选择排序字段的升序或降序,或者使用桶路径字段(例如,_count_key)。
  • from: 从指定的位置开始,截断在此之前的桶。
  • size: 返回的桶的数量。如果没有指定,默认返回所有父聚合的桶。

3. bucket_sort 聚合的常用参数

参数名 描述 是否必需 默认值
sort 排序字段列表,用于确定桶的排序顺序。 可选
from 用于截断前面桶的位置。 可选 0
size 返回的桶数量。 可选 所有桶
gap_policy 数据中缺失值时的处理策略。 可选 通过指定策略控制(详见下文)。

4. 示例 1:按总销售额排序并截取前三个月

假设有一个包含销售数据的索引,且希望按照每个月的总销售额进行排序,并返回销售额最高的前三个月。可以使用以下查询:

POST /sales/_search
{
  "size": 0,
  "aggs": {
    "sales_per_month": {
      "date_histogram": {
        "field": "date",
        "calendar_interval": "month"
      },
      "aggs": {
        "total_sales": {
          "sum": {
            "field": "price"
          }
        },
        "sales_bucket_sort": {
          "bucket_sort": {
            "sort": [
              { "total_sales": { "order": "desc" } }
            ],
            "size": 3
          }
        }
      }
    }
  }
}
  • sales_per_month:使用 date_histogram 聚合按照月份对销售数据进行分桶。
  • total_sales:计算每个月的总销售额。
  • sales_bucket_sort:应用 bucket_sort 聚合,按 total_sales 的降序进行排序,并限制返回前 3 个桶。

结果示例

{
   "took": 82,
   "timed_out": false,
   "_shards": ...,
   "hits": ...,
   "aggregations": {
      "sales_per_month": {
         "buckets": [
            {
               "key_as_string": "2015/01/01 00:00:00",
               "key": 1420070400000,
               "doc_count": 3,
               "total_sales": {
                   "value": 550.0
               }
            },
            {
               "key_as_string": "2015/03/01 00:00:00",
               "key": 1425168000000,
               "doc_count": 2,
               "total_sales": {
                   "value": 375.0
               }
            },
            {
               "key_as_string": "2015/02/01 00:00:00",
               "key": 1422748800000,
               "doc_count": 2,
               "total_sales": {
                   "value": 60.0
               }
            }
         ]
      }
   }
}

在这个例子中,返回了按照销售总额降序排序后的前三个月数据。

5. 示例 2:仅截取指定数量的桶

有时可能只想对返回的桶进行截断,而不对其排序。可以通过设置 fromsize 参数来实现,只截取特定范围的桶。例如,以下查询将返回第二个月的销售数据:

POST /sales/_search
{
  "size": 0,
  "aggs": {
    "sales_per_month": {
      "date_histogram": {
        "field": "date",
        "calendar_interval": "month"
      },
      "aggs": {
        "bucket_truncate": {
          "bucket_sort": {
            "from": 1,
            "size": 1
          }
        }
      }
    }
  }
}

结果示例

{
   "took": 11,
   "timed_out": false,
   "_shards": ...,
   "hits": ...,
   "aggregations": {
      "sales_per_month": {
         "buckets": [
            {
               "key_as_string": "2015/02/01 00:00:00",
               "key": 1422748800000,
               "doc_count": 2
            }
         ]
      }
   }
}

此查询将返回第二个月的桶,其他桶将被截断。

6. 处理数据中的缺失值(gap_policy)

在一些聚合中,数据可能存在缺失值。bucket_sort 聚合提供了 gap_policy 参数,用于处理这种情况。你可以设置以下选项:

  • skip:跳过缺失的值。
  • insert_zeros:为缺失的值插入零。

例如,如果你希望跳过缺失的桶,可以这样设置:

{
  "bucket_sort": {
    "sort": [
      { "total_sales": { "order": "desc" } }
    ],
    "gap_policy": "skip"
  }
}

其他参考DSL

在这里插入图片描述在这里插入图片描述


小结

bucket_sort 聚合提供了一种灵活的方式来对 Elasticsearch 聚合的结果进行排序,并且可以截断结果集,返回最感兴趣的桶。这对于数据分析和报告尤其有用,尤其是只关心排名靠前的数据时。通过合理配置 fromsizesort 参数,可以高效地获取所需的结果。

在这里插入图片描述


网站公告

今日签到

点亮在社区的每一天
去签到