嵌套桶编辑
(测试数据:http://blog.csdn.net/wwd0501/article/details/78501842)在我们使用不同的嵌套方案时,聚合的力量才能真正得以显现。 在前例中,我们以及看到如何将一个度量嵌入桶中,它的功能已经十分强大了。
但真正令人激动的分析来自于将桶嵌套进 另外一个桶 所能得到的结果。 现在,我们想知道每个颜色的汽车制造商的分布:
GET /cars/transactions/_search
{
"size" : 0,
"aggs": {
"colors": {
"terms": {
"field": "color"
},
"aggs": {
"avg_price": {
"avg": {
"field": "price"
}
},
"make": {
"terms": {
"field": "make"
}
}
}
}
}
}
注意前例中的 度量仍然保持原位。 | |
另一个聚合 被加入到了 颜色桶中。 | |
这个聚合是 桶,它会为每个汽车制造商生成唯一的桶。 |
这里发生了一些有趣的事。 首先,我们可能会观察到之前例子中的
avg_price
度量完全没有变化,还在原来的位置。 一个聚合的每个 层级 都可以有多个度量或桶,
avg_price
度量告诉我们每种颜色汽车的平均价格。它与其他的桶和度量相互独立。
这对我们的应用非常重要,因为这里面有很多相互关联,但又完全不同的度量需要收集。聚合使我们能够用一次数据请求获得所有的这些信息。
另外一件值得注意的重要事情是我们新增的这个
make
聚合,它是一个
terms
桶(嵌套在
colors
、
terms
桶内)。这意味着它 会为数据集中的每个唯一组合生成(
color
、
make
)元组。
让我们看看返回的响应(为了简单我们只显示部分结果):
{
...
"aggregations": {
"colors": {
"buckets": [
{
"key": "red",
"doc_count": 4,
"make": {
"buckets": [
{
"key": "honda",
"doc_count": 3
},
{
"key": "bmw",
"doc_count": 1
}
]
},
"avg_price": {
"value": 32500
}
},
...
}
正如期望的那样,新的聚合嵌入在每个颜色桶中。 | |
现在我们看见按不同制造商分解的每种颜色下车辆信息。 | |
最终,我们看到前例中的 度量仍然维持不变。 |
响应结果告诉我们以下几点:
- 红色车有四辆。
- 红色车的平均售价是 $32,500 美元。
- 其中三辆是 Honda 本田制造,一辆是 BMW 宝马制造。
Java代码实现:
/**
* Description:桶嵌套
* 例:计算每个颜色的汽车制造商的分布
* https://www.elastic.co/guide/cn/elasticsearch/guide/current/_buckets_inside_buckets.html
* @author wangweidong
* CreateTime: 2017年11月9日 下午3:47:54
*/
@Test
public void bucketsMetricsAggregation2() {
String index = "cars";
String type = "transactions";
SearchRequestBuilder searchRequestBuilder = client.prepareSearch(index).setTypes(type);
//颜色
TermsAggregationBuilder colorsField = AggregationBuilders.terms("popular_colors").field("color.keyword");
//平均价格
AvgAggregationBuilder avgPriceField = AggregationBuilders.avg("avg_price").field("price");
colorsField.subAggregation(avgPriceField);
//制造商
TermsAggregationBuilder makeField = AggregationBuilders.terms("make").field("make.keyword");
colorsField.subAggregation(makeField);
searchRequestBuilder.addAggregation(colorsField);
searchRequestBuilder.setSize(0);
SearchResponse searchResponse = searchRequestBuilder.execute().actionGet();
System.out.println(searchResponse.toString());
Terms genders = searchResponse.getAggregations().get("popular_colors");
for (Terms.Bucket entry : genders.getBuckets()) {
Object colorName = entry.getKey(); // Term
Long colorCount = entry.getDocCount(); // Doc count
Aggregations agg = entry.getAggregations();
Avg avg = agg.get("avg_price");
Double avgPrice = avg.getValue();
String info = "其中";
Terms makes = entry.getAggregations().get("make");
for (Terms.Bucket makeEntry : makes.getBuckets()) {
Object makeName = makeEntry.getKey();
Long makeCount = makeEntry.getDocCount();
info = info + makeCount + "辆是" + makeName + "制造,";
}
System.out.println(colorName + "车有" + colorCount + "辆,平均每台车价格:" + avgPrice + "," + info);
}
}
文章参考: https://www.elastic.co/guide/cn/elasticsearch/guide/current/_buckets_inside_buckets.html