1 2 3 4 5 6 7 8 9 10
| "aggregations" : { <!-- 最外层的聚合键,也可以缩写为 aggs --> "<aggregation_name>" : { <!-- 聚合的自定义名字 --> "<aggregation_type>" : { <!-- 聚合的类型,指标相关的,如 max、min、avg、sum,桶相关的 terms、filter 等 --> <aggregation_body> <!-- 聚合体:对哪些字段进行聚合,可以取字段的值,也可以是脚本计算的结果 --> } [,"meta" : { [<meta_data_body>] } ]? <!-- 元 --> [,"aggregations" : { [<sub_aggregation>]+ } ]? <!-- 在聚合里面在定义子聚合 --> } [,"<aggregation_name_2>" : { ... } ]* <!-- 聚合的自定义名字 2 --> }
|
可以聚合的前提是字段支持,如果text类型必须也有keyword类型。
指标聚合
Max Aggregation 用于最大值统计。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| # 统计 sales 索引中价格最高的是哪本书,并且计算出对应的价格的 2 倍值.指定的 field,在脚本中可以用 _value 取字段的值。 GET /sales/_search?size=0 { "aggs" : { "max_price" : { "max" : { "field" : "price" } }, "max_price_2" : { "max" : { "field" : "price", "script": { "source": "_value * 2.0" } } } } }
|
Min Aggregation 用于最小值统计。
1 2 3 4 5 6 7 8 9 10 11 12 13
| # 统计 sales 索引中价格最低的是哪本书.
GET /sales/_search?size=0 { "aggs" : { "min_price" : { "min" : { "field" : "price" } } } }
|
Avg Aggregation 用于计算平均值。
1 2 3 4 5 6 7 8 9 10 11 12
| # 统计 exams 索引中考试的平均分数,如未存在分数,默认为 60 分.如果指定字段没有值,可以通过 missing 指定默认值;若未指定默认值,缺失该字段值的文档将被忽略(计算)。 GET /exams/_search?size=0 { "aggs" : { "avg_grade" : { "avg" : { "field" : "grade", "missing": 60 } } } }
|
Sum Aggregation 用于计算总和。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| # 统计 sales 索引中 type 字段中匹配 hat 的价格总和 GET /exams/_search?size=0 { "query" : { "constant_score" : { "filter" : { "match" : { "type" : "hat" } } } }, "aggs" : { "hat_prices" : { "sum" : { "field" : "price" } } } }
|
Value Count Aggregation 可按字段统计文档数量。
1 2 3 4 5 6 7 8 9
| # 统计 books 索引中包含 author 字段的文档数量 GET /books/_search?size=0 { "aggs" : { "doc_count" : { "value_count" : { "field" : "author" } } } }
|
Cardinality Aggregation 用于基数统计,其作用是先执行类似 SQL 中的 distinct 操作,去掉集合中的重复项,然后统计排重后的集合长度
1 2 3 4 5 6 7 8 9 10 11 12 13
| # 在 books 索引中对 language 字段进行 cardinality 操作可以统计出编程语言的种类数 GET /books/_search?size=0 { "aggs" : { "all_lan" : { "cardinality" : { "field" : "language" } }, "title_cnt" : { "cardinality" : { "field" : "title.keyword" } } } } # 假设 title 字段为文本类型(text),去重时需要指定 keyword,表示把 title 作为整体去重,即不分词统计。
|
Stats Aggregation 用于基本统计,会一次返回 count、max、min、avg 和 sum 这 5 个指标。
1 2 3 4 5 6 7 8 9
| # 在 exams 索引中对 grade 字段进行分数相关的基本统计 GET /exams/_search?size=0 { "aggs" : { "grades_stats" : { "stats" : { "field" : "grade" } } } }
|
Extended Stats Aggregation 用于高级统计,和基本统计功能类似,但是会比基本统计多出以下几个统计结果,sum_of_squares(平方和)、variance(方差)、std_deviation(标准差)、std_deviation_bounds(平均值加/减两个标准差的区间)。
1 2 3 4 5 6 7 8 9
| # 在 exams 索引中对 grade 字段进行分数相关的高级统计 GET /exams/_search?size=0 { "aggs" : { "grades_stats" : { "extended_stats" : { "field" : "grade" } } } }
|
Percentiles Aggregation 用于百分位统计。百分位数是一个统计学术语,如果将一组数据从大到小排序,并计算相应的累计百分位,某一百分位所对应数据的值就称为这一百分位的百分位数。默认情况下,累计百分位为 [ 1, 5, 25, 50, 75, 95, 99 ]。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
| # 在 latency 索引中对 load_time 字段进行加载时间的百分位统计 GET latency/_search { "size": 0, "aggs" : { "load_time_outlier" : { "percentiles" : { "field" : "load_time" } } } } # 需要注意的是,如上的 load_time 字段必须是数字类型。
# 百分位的统计也可以指定 percents 参数指定百分位,如下: GET latency/_search { "size": 0, "aggs" : { "load_time_outlier" : { "percentiles" : { "field" : "load_time", "percents": [60, 80, 95] } } } }
|
Percentiles Ranks Aggregation 与 Percentiles Aggregation 统计恰恰相反,就是想看当前数值处在什么范围内(百分位)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
| # 查一下当前值 500 和 600 所处的百分位,发现是 90.01 和 100,那么说明有 90.01 % 的数值都在 500 以内,100 % 的数值在 600 以内。 GET latency/_search { "size": 0, "aggs" : { "load_time_ranks" : { "percentile_ranks" : { "field" : "load_time", "values" : [500, 600] } } } } # 同样 load_time 字段必须是数字类型。
# 可以设置 keyed 参数为 true,将对应的 values 作为桶 key 一起返回,默认是 false。 GET latency/_search { "size": 0, "aggs": { "load_time_ranks": { "percentile_ranks": { "field": "load_time", "values": [500, 600], "keyed": true } } } }
|
桶聚合
bucket 可以理解为一个桶,它会遍历文档中的内容,凡是符合某一要求的就放入一个桶中,分桶相当于 SQL 中的 group by。从另外一个角度,可以将指标聚合看成单桶聚合,即把所有文档放到一个桶中,而桶聚合是多桶型聚合,它根据相应的条件进行分组。
Terms Aggregation
Terms Aggregation 用于词项的分组聚合。最为经典的用例是获取 X 中最频繁(top frequent)的项目,其中 X 是文档中的某个字段,如用户的名称、标签或分类。由于 terms 聚集统计的是每个词条,而不是整个字段值,因此通常需要在一个非分析型的字段上运行这种聚集。原因是, 你期望“big data”作为词组统计,而不是“big”单独统计一次,“data”再单独统计一次。
用户可以使用 terms 聚集,从分析型字段(如内容)中抽取最为频繁的词条。还可以使用这种信息来生成一个单词云。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
| { "aggs": { "profit_terms": { "terms": { // terms 聚合 关键字 "field": "profit", ...... } } } }
GET /bunny/_search { "query": { "match": { "title": "石油 测试" } }, "aggs": { "group_by_state": { "terms": { "field": "category.keyword" } }, "group_by_state2": { "terms": { "field": "issuingAgency.keyword" } } } }
|
在 terms 分桶的基础上,还可以对每个桶进行指标统计,也可以基于一些指标或字段值进行排序。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
| { "aggs": { "item_terms": { "terms": { "field": "item_id", "size": 1000, "order":[{ "gmv_stat": "desc" },{ "gmv_180d": "desc" }] }, "aggs": { "gmv_stat": { "sum": { "field": "gmv" } }, "gmv_180d": { "sum": { "script": "doc['gmv_90d'].value*2" } } } } } }
|
默认情况下返回按文档计数从高到低的前 10 个分组,可以通过 size 参数指定返回的分组数。
Filter Aggregation
Filter Aggregation 是过滤器聚合,可以把符合过滤器中的条件的文档分到一个桶中,即是单分组聚合。
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| { "aggs": { "age_terms": { "filter": {"match":{"gender":"F"}}, "aggs": { "avg_age": { "avg": { "field": "age" } } } } } }
|
Filters Aggregation
Filters Aggregation 是多过滤器聚合,可以把符合多个过滤条件的文档分到不同的桶中,即每个分组关联一个过滤条件,并收集所有满足自身过滤条件的文档。
1 2 3 4 5 6 7 8 9 10 11 12 13
| { "size": 0, "aggs": { "messages": { "filters": { "filters": { "bunny": { "match": { "body": "bunny" } }, "kitty": { "match": { "body": "kitty" } } } } } } }
|
Range Aggregation
Range Aggregation 范围聚合是一个基于多组值来源的聚合,可以让用户定义一系列范围,每个范围代表一个分组。在聚合执行的过程中,从每个文档提取出来的值都会检查每个分组的范围,并且使相关的文档落入分组中。注意,范围聚合的每个范围内包含 from 值但是排除 to 值。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
| "aggs": { "age_range": { "range": { "field": "age", "ranges": [{ "to": 25 }, { "from": 25, "to": 35 }, { "from": 35 }] }, "aggs": { "bmax": { "max": { "field": "balance" } } } } }
|