资讯动态

[ELK实战] Elasticsearch 聚合查询二: Bucketing/桶聚合

发布时间:2026/9/23 8:50:47 来源:尧图企业网站定制
简介目前在官方文档有4种聚合(Aggregations )方式分别是Metric (指标聚合):最常用的聚合方式例如 平均值,求和等等Bucketing (桶聚合):就是常说的分组聚合Matrix (矩阵聚合) :在多个字段上操作并根据从请求的文档字段提取的值生成矩阵结果的聚合族。与度量聚合和桶聚合不同此聚合族尚不支持脚本。Pipeline (管道聚合):由于每个 bucket 有效地定义了一个文档集(属于 bucket 的所有文档) 因此可以潜在地在 bucket 级别上关联聚合并且这些聚合将在 bucket 的上下文中执行。这就是聚合的真正威力所在: 聚合可以被嵌套方法 / 步骤一 简介并加入测试数据1.1 聚合相关参数指标聚合有参数有range / date_range / terms / histogram / date_histogram / …聚合类型聚合参数简介BucketingRange Aggregation- 范围聚合查询BucketingDate Range Aggregation- 时间范围聚合查询BucketingTerms Aggregation- 分组统计BucketingHistogram Aggregation- 直方图统计BucketingDate histogram aggregation- 时间直方图统计1.2 DSL 查询格式aggregations:{aggregation_name:{aggregation_type:{aggregation_body}[,meta:{[meta_data_body]}]?[,aggregations:{[sub_aggregation]}]?}[,aggregation_name_2:{...}]*}1.3 插入批量测试数据POST/staff/_bulk{index:{_id:1}}{name:zs,realname:张三,age:10,birthday:2018-12-27,salary:1000.0,address:北京市北海公园}{index:{_id:2}}{name:ls,realname:李四,age:20,birthday:2017-10-20,salary:2000.0,address:北京市京东大峡谷}{index:{_id:3}}{name:ww,realname:王五,age:30,birthday:2016-03-15,salary:3000.0,address:北京市陶然亭}{index:{_id:4}}{name:zl,realname:赵六,age:40,birthday:2003-04-19,salary:4000.0,address:北京市玉渊潭}{index:{_id:5}}{name:tq,realname:田七,age:50,birthday:2001-08-11,salary:5000.0,address:北京市圆明园}插入完成后查看索引数据GET/staff/_search二: 常规查询2.1 Range Aggregation / 返回聚合每个范围表示一个桶。在聚合过程中将根据每个bucket范围和相关/匹配文档的“bucket”检查从每个文档提取的值。如 统计0-20岁20-40岁40~60岁各个区间段的用户人数POST/staff/_search {aggs: {age_ranges_count: {range: {field:age,ranges:[{from:0,to:20},{from:20,to:40},{from:40,to:60}]} } } }返回内容.....aggregations: {age_ranges_count: {buckets:[{key:0.0-20.0,from:0.0,to:20.0,doc_count:1},{key:20.0-40.0,from:20.0,to:40.0,doc_count:2},{key:40.0-60.0,from:40.0,to:60.0,doc_count:2}]} }.....如果第一个区间开始值和最后一个区间结束值不想指定的话可以不用写from和to如下POST/staff/_search {aggs: {age_ranges_count: {range: {field:age,ranges:[{to:20},{from:20,to:40},{from:40,to:60}]} } } }返回内容....aggregations: {age_ranges_count: {buckets:[{key:*-20.0,to:20.0,doc_count:1},{key:20.0-40.0,from:20.0,to:40.0,doc_count:2},{key:40.0-60.0,from:40.0,to:60.0,doc_count:2}]} }....2.2 Date Range Aggregation / 时间范围聚合此聚合与Range Aggregation常规范围聚合的主要区别在于可以用日期数学表达式表示from和to值而且还可以指定返回from和to响应字段的日期格式。注意此聚合包含每个范围的from值并排除to值。now10y表示从现在开始的第10年。now10M表示从现在开始的第10个月。1990-01-10||20y表示从1990-01-01开始后的第20年即2010-01-01。now/y表示在年位上做舍入运算。如 统计生日在2017年、2018年、2019年的用户now/y当前年的1月1日now当前时间now/y-1y当前年上一年的1月1日POST /staff/_search{aggs:{birthday_count:{date_range:{field:birthday,format:yyyy-MM-dd,ranges:[{from:now/y-1y,to:now/y},{from:now/y-2y,to:now/y-1y},{from:now/y-3y,to:now/y-2y}]}}}}返回数据aggregations:{birthday_count:{buckets:[{key:2019-01-01-2020-01-01,from:1.5463008E12,from_as_string:2019-01-01,to:1.5778368E12,to_as_string:2020-01-01,doc_count:0},{key:2020-01-01-2021-01-01,from:1.5778368E12,from_as_string:2020-01-01,to:1.6094592E12,to_as_string:2021-01-01,doc_count:0},{key:2021-01-01-2022-01-01,from:1.6094592E12,from_as_string:2021-01-01,to:1.6409952E12,to_as_string:2022-01-01,doc_count:0}]}}2.3 Terms Aggregation / 分组聚合对年龄进行聚合,显示3条数据POST/staff/_search {aggs: {age_count: {terms: {field:age,size:3} } } }聚合结果key年龄 为1020 30各为一条......aggregations: {age_count: {doc_count_error_upper_bound:0,sum_other_doc_count:2,buckets:[{key:10,doc_count:1},{key:20,doc_count:1},{key:30,doc_count:1}]} }......2.4 Histogram Aggregation / 直方图聚合它与前面介绍的Range聚合非常像只不过Range可以任意划分区间而Histogram做等间距划分。既然是等间距划分那么参数里面必然有距离参数就是interval参数。如根据年龄间隔20岁统计各个年龄段的员工总人数POST/staff/_search?size0{aggs: {salary_value_count: {value_count: {field:salary} } } }返回结果.....aggregations: {age_histogram_count: {buckets:[{key:0.0,doc_count:1},{key:20.0,doc_count:2},{key:40.0,doc_count:2}]} }.....2.5 Date histogram aggregation / 时间直方图聚合日期直方图聚合专门对时间类型的字段做直方图聚合。这种需求是比较常用见得的我们在统计时通常就会按照固定的时间断1个月或1年等来做统计如按年统计用户生日的总人数POST /staff/_search{aggs:{birthday_data_histogram_count:{date_histogram:{field:birthday,interval:year,format:yyyy-MM-dd}}}}返回结果.....aggregations: {birthday_data_histogram_count: {buckets:[{key_as_string:2001-01-01,key:978307200000,doc_count:1},{key_as_string:2002-01-01,key:1009843200000,doc_count:0},{key_as_string:2003-01-01,key:1041379200000,doc_count:1},{key_as_string:2004-01-01,key:1072915200000,doc_count:0},{key_as_string:2005-01-01,key:1104537600000,doc_count:0},{key_as_string:2006-01-01,key:1136073600000,doc_count:0},{key_as_string:2007-01-01,key:1167609600000,doc_count:0},{key_as_string:2008-01-01,key:1199145600000,doc_count:0},{key_as_string:2009-01-01,key:1230768000000,doc_count:0},{key_as_string:2010-01-01,key:1262304000000,doc_count:0},{key_as_string:2011-01-01,key:1293840000000,doc_count:0},{key_as_string:2012-01-01,key:1325376000000,doc_count:0},{key_as_string:2013-01-01,key:1356998400000,doc_count:0},{key_as_string:2014-01-01,key:1388534400000,doc_count:0},{key_as_string:2015-01-01,key:1420070400000,doc_count:0},{key_as_string:2016-01-01,key:1451606400000,doc_count:1},{key_as_string:2017-01-01,key:1483228800000,doc_count:1},{key_as_string:2018-01-01,key:1514764800000,doc_count:1}]} }.....三: 聚合查询嵌套使用通过嵌套可以使得metric类型的聚合操作作用在每一bucket上。我们可以使用ES的嵌套聚合操作来完成稍微复杂一点的统计功能。3.1 统计每年中用户的最高工资POST /staff/_search{aggs:{birthday_data_histogram_count:{date_histogram:{field:birthday,interval:year,format:yyyy-MM-dd},aggs:{max_salary:{max:{field:salary}}}}}}返回结果.....aggregations: {birthday_data_histogram_count: {buckets:[{key_as_string:2001-01-01,key:978307200000,doc_count:1,max_salary: {value:5000.0} },{key_as_string:2002-01-01,key:1009843200000,doc_count:0,max_salary: {value:null} },{key_as_string:2003-01-01,key:1041379200000,doc_count:1,max_salary: {value:4000.0} },{key_as_string:2004-01-01,key:1072915200000,doc_count:0,max_salary: {value:null} },{key_as_string:2005-01-01,key:1104537600000,doc_count:0,max_salary: {value:null} },{key_as_string:2006-01-01,key:1136073600000,doc_count:0,max_salary: {value:null} },{key_as_string:2007-01-01,key:1167609600000,doc_count:0,max_salary: {value:null} },{key_as_string:2008-01-01,key:1199145600000,doc_count:0,max_salary: {value:null} },{key_as_string:2009-01-01,key:1230768000000,doc_count:0,max_salary: {value:null} },{key_as_string:2010-01-01,key:1262304000000,doc_count:0,max_salary: {value:null} },{key_as_string:2011-01-01,key:1293840000000,doc_count:0,max_salary: {value:null} },{key_as_string:2012-01-01,key:1325376000000,doc_count:0,max_salary: {value:null} },{key_as_string:2013-01-01,key:1356998400000,doc_count:0,max_salary: {value:null} },{key_as_string:2014-01-01,key:1388534400000,doc_count:0,max_salary: {value:null} },{key_as_string:2015-01-01,key:1420070400000,doc_count:0,max_salary: {value:null} },{key_as_string:2016-01-01,key:1451606400000,doc_count:1,max_salary: {value:3000.0} },{key_as_string:2017-01-01,key:1483228800000,doc_count:1,max_salary: {value:2000.0} },{key_as_string:2018-01-01,key:1514764800000,doc_count:1,max_salary: {value:1000.0} }]} }.....先通过date_histogram按照年分组然后再通过嵌套max聚合查询统计出每年最高工资是多少。3.2 求每个年龄区间段的工资总和....aggregations: {age_ranges_count: {buckets:[{key:0.0-20.0,from:0.0,to:20.0,doc_count:1,sum_salary: {value:1000.0} },{key:20.0-40.0,from:20.0,to:40.0,doc_count:2,sum_salary: {value:5000.0} },{key:40.0-60.0,from:40.0,to:60.0,doc_count:2,sum_salary: {value:9000.0} }]} }....参考资料 致谢[1]官方文档[2] ElasticSearch全文搜索引擎之Aggregation聚合查询(结合Kibana)

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价