概述
先来看一个需求
现在有一堆数据,是每个演员的每个电影的评论,现在我们要取到10个演员的评论数量排名前5的电影
看一下请求体1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19{
"aggs" : {
"actors" : {
"terms" : {
"field" : "actors",
"size" : 10,
"collect_mode" : "breadth_first"
},
"aggs" : {
"costars" : {
"terms" : {
"field" : "films",
"size" : 5
}
}
}
}
}
}
第一个聚合,根据演员分组,就能拿到每个演员的评论的数量, 然后 size是10 取前10个,collect_mode先不管,然后是第二个按电影分组,拿到了每个演员每个电影的评论数量,取前5的电影,这个需求就ok了
接下来看一下深度优先和广度优先的两种聚合方式
深度优先的聚合方式
假设每个演员对应的电影数据如下1
2 actor1 actor2 .... actor
film1 film2 film3 film1 film2 film3 ...film
比如说,现在有10万个actor,其实最后只需要10个就好了
但是我们使用的是深度优先的方式,它已经构建了一颗完整的树出来了,假设每个actor有10个电影, 那就是10万actor + 100万film的数据量的树.
最后再裁剪掉10万个actor中的99990个actor和99990 10 个film,剩下10个actor, 每个actor再裁剪掉5个film,剩下的数据就是10 5 = 50个, 从110万的数据裁剪成5个.
先构建了大量的数据,最后裁掉99.99%的数据,浪费了
广度优先的方式执行
先构建actor的数,如下1
actor1 actor2 actor3 ..... n个actor
假设10万个actor,但是现在不去构建他下面的film数据, 数据量也就是10万个,然后裁掉99990个 剩下10个,这个时候再去构建film,裁剪掉5个
数据就是从10万到剩下的50个,比上面的深度优先性能高了10倍.
再看上面那个请求体,其中collect_mode参数值为breadth_first,就是表示广度优先