文章目录
原文: https://www.cnblogs.com/qdhxhz/p/11556764.html
官方对聚合有四个关键字:Metric(指标)、Bucketing(桶)、Matrix(矩阵)、Pipeline(管道)。
1. 聚合概念
1.1 ES聚合分析是什么?
Elasticsearch除全文检索功能外提供的针对Elasticsearch数据做统计分析的功能。它的实时性高,所有的计算结果都是即时返回。
Elasticsearch将聚合分析主要分为如下4类:
Metric(指标): 指标分析类型,如计算最大值、最小值、平均值等等 (对桶内的文档进行聚合分析的操作)
Bucket(桶): 分桶类型,类似SQL中的GROUP BY语法 (满足特定条件的文档的集合)
Pipeline(管道): 管道分析类型,基于上一级的聚合分析结果进行在分析
Matrix(矩阵): 矩阵分析类型(聚合是一种面向数值型的聚合,用于计算一组文档字段中的统计信息)
1.2 聚合分析查询语法
"aggregations" : {
"<aggregation_name>" : { <!--聚合的名字 -->
"<aggregation_type>" : { <!--聚合的类型 -->
<aggregation_body> <!--聚合体:对哪些字段进行聚合 -->
}
[,"meta" : { [<meta_data_body>] } ]? <!--元 -->
[,"aggregations" : { [<sub_aggregation>]+ } ]? <!--在聚合里面在定义子聚合 -->
}
[,"<aggregation_name_2>" : { ... } ]* <!--聚合的名字 -->
}
注意:aggregations 也可简写为 aggs
1.3 指标(metric)和 桶(bucket)
虽然Elasticsearch有四种聚合方式,但在一般实际开发中,用到的比较多的就是Metric和Bucket。
(1)桶(bucket)
- 简单来说桶就是满足特定条件的文档的集合。
- 当聚合开始被执行,每个文档里面的值通过计算来决定符合哪个桶的条件,如果匹配到,文档将放入相应的桶并接着开始聚合操作。
- 桶也可以被嵌套在其他桶里面。
(2) 指标(metric)
- 桶能让我们划分文档到有意义的集合,但是最终我们需要的是对这些桶内的文档进行一些指标的计算。分桶是一种达到目的地的手段:它提供了一种给文档分组的方法来让我们可以计算感兴趣的指标;
- 大多数指标是简单的数学运算(如:最小值、平均值、最大值、汇总),这些是通过文档的值来计算的。
2. 指标(Metric)详解
Metric聚合分析分为单值分析和多值分析两类:
#1、单值分析,只输出一个分析结果
min,max,avg,sum,cardinality
#2、多值分析,输出多个分析结果
stats,extended_stats,percentile,percentile_rank,top hits
- Avg(平均值)
计算从聚合文档中提取的数值的平均值
POST /exams/_search?size=0
{
"aggs" : {
"avg_grade" : { "avg" : { "field" : "grade" } }
}
}
3. Gulimall聚合练习
3.1 terms、avg聚合
# 搜索address中包含mill的所有人的年龄分布以及平均年龄
GET /bank/_search
{
"query": {
"match": {
"address": "mill"
}
},
"aggs": {
"aggAge": {
"terms": {
"field": "age",
"size": 100
}
},
"aggAvg":{
"avg": {
"field": "age"
}
}
}
}
# 按照年龄聚合,而且请求这些年龄段的这些人的平均薪资
GET /bank/_search
{
"aggs": {
"aggAge": {
"terms": {
"field": "age",
"size": 100
},
"aggs": {
"aggAvg": {
"avg": {
"field": "balance"
}
}
}
}
}
}
# 查出所有年龄分布,并且这些年龄段中M的平均薪资和F的平均薪资以及这个年龄段的总体平均薪资
GET /bank/_search
{
"aggs": {
"aggAge": {
"terms": {
"field": "age",
"size": 100
},
"aggs": {
"aggSex": {
"terms": {
"field": "gender.keyword",
"size": 2
},
"aggs": {
"balanceAvg": {
"avg": {
"field": "balance"
}
}
}
},
"aggAvgAll": {
"avg": {
"field": "balance"
}
}
}
}
}
}
3.2 percentiles
对指定字段的值按从小到大累计每个值对应的文档数的占比,返回指定占比比例对应的值。
(即:通过百分比求文档值)
- 默认取百分比
请求:
# 统计年龄占比
GET /bank/_search
{
"size": 0,
"aggs": {
"agg1": {
"percentiles": {
"field": "age"
}
}
}
}
返回:
{
"took" : 2,
"timed_out" : false,
"_shards" : {
"total" : 1,
"successful" : 1,
"skipped" : 0,
"failed" : 0
},
"hits" : {
"total" : {
"value" : 1000,
"relation" : "eq"
},
"max_score" : null,
"hits" : [ ]
},
"aggregations" : {
"agg1" : {
"values" : {
"1.0" : 20.0,
"5.0" : 21.0,
"25.0" : 25.0,
"50.0" : 30.8125,
"75.0" : 35.0,
"95.0" : 39.0,
"99.0" : 40.0
}
}
}
}
说明:
(1)默认按照[ 1, 5, 25, 50, 75, 95, 99 ]来统计
(2)返回结果可以理解为:占比为75%的文档的age值 <= 35.0,或反过来:age<=35.0的文档数占总命中文档数的75%
- 指定分位值
请求:
# 统计的男女占比
GET /bank/_search
{
"size":0,
"aggs": {
"agg1": {
"percentiles": {
"field": "age",
"percents": [
60,
80,
100
],
"keyed": false
}
}
}
}
返回:
{
"took" : 2,
"timed_out" : false,
"_shards" : {
"total" : 1,
"successful" : 1,
"skipped" : 0,
"failed" : 0
},
"hits" : {
"total" : {
"value" : 1000,
"relation" : "eq"
},
"max_score" : null,
"hits" : [ ]
},
"aggregations" : {
"agg1" : {
"values" : [
{
"key" : 60.0,
"value" : 32.0
},
{
"key" : 80.0,
"value" : 36.0
},
{
"key" : 100.0,
"value" : 40.0
}
]
}
}
}
说明:
(1)默认情况下,keyed标志设置为true,它将唯一的字符串键与每个存储桶相关联,并将范围作为哈希而不是数组返回。
3.3 Percentile Ranks
上面是通过百分比求文档值,这里通过文档值求百分比。
请求:
# 根据文档值求百分比
GET /bank/_search
{
"size":0,
"aggs":{
"agg1":{
"percentile_ranks": {
"field": "age",
"values": [
32,
36,
40
]
}
}
}
}
返回:
{
"took" : 0,
"timed_out" : false,
"_shards" : {
"total" : 1,
"successful" : 1,
"skipped" : 0,
"failed" : 0
},
"hits" : {
"total" : {
"value" : 1000,
"relation" : "eq"
},
"max_score" : null,
"hits" : [ ]
},
"aggregations" : {
"agg1" : {
"values" : {
"32.0" : 60.3,
"36.0" : 80.80000000000001,
"40.0" : 100.0
}
}
}
}
说明:
(1)age小于32.0的文档占比为60.3%,age小于36.0的文档占比为80.8%,