0%

ElasticSearch-聚合的作用范围及排序

1. 作用范围

ES 聚合分析的默认作⽤范围是 query 的查询结果集,同时 ES 还⽀持以下⽅式改变聚合的作⽤范围:

  • Filter
  • Post_Filter
  • Global

下述示例中,查询响应只返回员工年龄大于等于 20 的记录的聚合结果:

query 查询结果集限制聚合范围

1.1 filter

filter 支持对聚合结果做条件过滤,从而限制其聚合作用范围。查看下述示例中,在对 job.keyword 进行分桶时,通过增加 filter 将分桶限定在员工年龄大于 35 的记录上。不过,我们可以在外层增加 all_jobs来返回得到未进行条件限定的分桶聚合信息:

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
POST employees/_search
{
"size": 0,
"aggs": {
"older_person": {
"filter":{
"range":{
"age":{
"from":35
}
}
},
"aggs":{
"jobs":{
"terms": {
"field":"job.keyword"
}
}
}},
"all_jobs": {
"terms": {
"field":"job.keyword"
}
}
}
}

响应信息如下:

1.2 post_filter

post_filter 是对聚合分析后的⽂档进⾏再次过滤,例如对员工信息按照 job.keyword 进行分桶聚合的基础上过滤出指定 job.keyword 的记录,示例如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
POST employees/_search
{
"aggs": {
"jobs": {
"terms": {
"field": "job.keyword"
}
}
},
"post_filter": {
"match": {
"job.keyword": "Dev Manager"
}
}
}

响应信息:

1.3 global

为了避免 query 对聚合的作用范围限定,可以采用 global 来对全部文档进行统计。观察下述示例,聚合子查询 jobs 还是在 query 的作用范围内,而聚合子查询 salary_avg 则由于增加了 "global:{}"从而避免 query 的限定:

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
32
33
34
35
36
37
38
39
40
41
POST employees/_search
{
"size": 10,
"query": {
"range": {
"age": {
"gte": 40
}
}
},
"aggs": {
"jobs": {
"terms": {
"field":"job.keyword"
}
},
"all":{ // 自定义名称 all
"global":{},
"aggs":{
"salary_avg":{
"avg":{
"field":"salary"
}
}
}
}
}
}

// 聚合查询 salary_avg 同下
POST employees/_search
{
"size": 0,
"aggs": {
"salary_avg": {
"avg": {
"field": "salary"
}
}
}
}

响应信息如下:

2. 排序

聚合时可以指定 order, 按照 count 和 key 进⾏排序。默认情况,按照 count 降序排序,指定 size,就能返回相应的桶。比如下述示例中,对年龄大于等于 20 的员工按照 job.keyword 进行分桶聚合,同时对分桶按照文档数量和 key(即 job.keyword 的值)分别进行升序和降序排序:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
POST employees/_search
{
"size": 0,
"query": {
"range": {
"age": {
"gte": 20
}
}
},
"aggs": {
"jobs": {
"terms": {
"field":"job.keyword",
"order":[
{"_count":"asc"},
{"_key":"desc"}
]
}
}
}
}

响应信息如下:

我们也可以基于⼦聚合的数值进⾏排序,比如下述示例中先对员工按照 job.keyword 进行分桶聚合,然后对分桶按照另一个聚合统计即员工平均工资进行逆序排序:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
POST employees/_search
{
"size": 0,
"aggs": {
"jobs": {
"terms": {
"field":"job.keyword",
"order":[ {
"avg_salary":"desc"
}]
},
"aggs": {
"avg_salary": {
"avg": {
"field":"salary"
}
}
}
}
}
}

响应信息如下:

metrix aggregation 采用 stats 时也可以采用下述方式以达到同样的执行效果:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
POST employees/_search
{
"size": 0,
"aggs": {
"jobs": {
"terms": {
"field":"job.keyword",
"order":[ {
"stats_salary.avg":"desc"
}]
},
"aggs": {
"stats_salary": {
"stats": {
"field":"salary"
}
}
}
}
}
}
------ 本文结束------