GeekIBLi

嵌套桶

2021-07-08

两层嵌套

在我们使用不同的嵌套方案时,聚合的力量才能真正得以显现。 在前例中,我们已经看到如何将一个度量嵌入桶中,它的功能已经十分强大了。

但真正令人激动的分析来自于将桶嵌套进 另外一个桶 所能得到的结果。 现在,我们想知道每个颜色的汽车制造商的分布:

GET /cars/transactions/_search

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
{
"size" : 0,
"aggs": {
"colors": {
"terms": {
"field": "color"
},
"aggs": {
"avg_price": {
"avg": {
"field": "price"
}
},
"make": {
"terms": {
"field": "make"
}
}
}
}
}
}
  • 注意前例中的 avg_price 度量仍然保持原位。

  • 另一个聚合 make 被加入到了 color 颜色桶中。

  • 这个聚合是 terms 桶,它会为每个汽车制造商生成唯一的桶。

这里发生了一些有趣的事。 首先,我们可能会观察到之前例子中的 avg_price 度量完全没有变化,还在原来的位置。 一个聚合的每个 层级 都可以有多个度量或桶, avg_price 度量告诉我们每种颜色汽车的平均价格。它与其他的桶和度量相互独立。

这对我们的应用非常重要,因为这里面有很多相互关联,但又完全不同的度量需要收集。聚合使我们能够用一次数据请求获得所有的这些信息。

另外一件值得注意的重要事情是我们新增的这个 make 聚合,它是一个 terms 桶(嵌套在 colors 、 terms 桶内)。这意味着它会为数据集中的每个唯一组合生成( color 、 make )元组。

让我们看看返回的响应(为了简单我们只显示部分结果):

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
{
"aggregations": {
"colors": {
"buckets": [
{
"key": "red",
"doc_count": 4,
"make": {
"buckets": [
{
"key": "honda",
"doc_count": 3
},
{
"key": "bmw",
"doc_count": 1
}
]
},
"avg_price": {
"value": 32500
}
}
}
}
}
  • 正如期望的那样,新的聚合嵌入在每个颜色桶中。

  • 现在我们看见按不同制造商分解的每种颜色下车辆信息。

  • 最终,我们看到前例中的 avg_price 度量仍然维持不变。

三层嵌套

让我们回到话题的原点,在进入新话题之前,对我们的示例做最后一个修改, 为每个汽车生成商计算最低和最高的价格:
GET /cars/transactions/_search

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
{
"size" : 0,
"aggs": {
"colors": {
"terms": {
"field": "color"
},
"aggs": {
"avg_price": { "avg": { "field": "price" }
},
"make" : {
"terms" : {
"field" : "make"
},
"aggs" : {
"min_price" : { "min": { "field": "price"} },
"max_price" : { "max": { "field": "price"} }
}
}
}
}
}
}
  • 我们需要增加另外一个嵌套的 aggs 层级。

  • 然后包括 min 最小度量。

  • 以及 max 最大度量。

得到以下输出(只显示部分结果):

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
{
...
"aggregations": {
"colors": {
"buckets": [
{
"key": "red",
"doc_count": 4,
"make": {
"buckets": [
{
"key": "honda",
"doc_count": 3,
"min_price": {
"value": 10000
},
"max_price": {
"value": 20000
}
},
{
"key": "bmw",
"doc_count": 1,
"min_price": {
"value": 80000
},
"max_price": {
"value": 80000
}
}
]
},
"avg_price": {
"value": 32500
}
},
...

有了这两个桶,我们可以对查询的结果进行扩展并得到以下信息:

有四辆红色车。
红色车的平均售价是 $32,500 美元。
其中三辆红色车是 Honda 本田制造,一辆是 BMW 宝马制造。
最便宜的红色本田售价为 $10,000 美元。
最贵的红色本田售价为 $20,000 美元。