},
“aggregations” : { —聚合结果
“popular_colors” : { —聚合字段
“doc_count_error_upper_bound” : 0,
“sum_other_doc_count” : 0,
“buckets” : [ —这个数组的元素是所有的桶
{
“key” : “blue”, —color为blue的文档
“doc_count” : 1 —文档数为1
},
{
“key” : “green”, —color为blue的文档
“doc_count” : 1 —文档数为1
}
]
}
}
}
[](()全局桶
如果想对比福特汽车的销售额和所有汽车的销售额,可以通过全局桶对所有文档做聚合,关键字是global,全局桶的聚合不受范围限定的影响:
GET /cars/transactions/_search
{
“size”: 0,
“query”: { —范围限定的查询
“term”: { —查询类型是精确匹配
“make”: “ford” —查询条件是品牌为福特
}
},
“aggs”: { —聚合
“ford_sales”: { —聚合字段名
“sum”: { —直接对范围内的所有文档执行metrics,类型是累加
“field”: “price” —选择price字段的值进行累加
}
},
“all”: { —聚合字段名
“global”: {}, —全局桶关键字,表示忽略前面term查询的范围限定
“aggs”: { —聚合
“all_sales”: { —聚合字段名
“sum”: { —直接对范围内的所有文档执行metrics,类型是累加
“field”: “price” —选择price字段的值进行累加
}
}
}
}
}
}
来看看结果:
…
“aggregations” : { —聚合结果
“all” : { —全局桶的聚合结果(term查询无效)
“doc_count” : 8, —文档总数
“all_sales” : { —聚合字段名
“value” : 212000.0 —总销售额
}
},
“ford_sales” : { —聚合字段名(term查询限定了范围,只有福特汽车的销售记录)
“value” : 55000.0 —福特汽车销售额
}
}
}
[](()不止是query
前面的范围限定用到了query,其实适用于查询的过滤器也能应用在聚合操作中,下面是过滤+聚合的查询,和前面一样,也是统计总销售和和福特汽车的销售额:
GET /cars/transactions/_search
{
“size”: 0,
“query”: {
“bool”: { —布尔查询,里面可以将query和filter组合使用
“filter”: { —本例只用到了filter
“term”: { —精确匹配
“make”: “ford” —匹配福特品牌
}
}
}
},
“aggs”: { —聚合结果
“ford_sales”: { —聚合字段名
“sum”: { —metrics操作,累加
“field”: “price” —累加字段是price
}
},
“all”: { —聚合字段名
“global”: {}, —全局桶关键字,表示忽略范围限定
“aggs”: { —聚合
“all_sales”: { —聚合字段名
“sum”: { —metrics操作,累加
“field”: “price” —累加字段是price
}
}
}
}
}
}
查询结果如下,和query的一样:
…
“aggregations” : {
“all” : {
“doc_count” : 8,
“all_sales” : {
“value” : 212000.0
}
},
“ford_sales” : {
“value” : 55000.0
}
}
}
注意:虽然query和filter限定范围的结果是一样的,但是filter会忽略评分,并且有可能缓存结果数据,这些都是性能上的优势;
[](()桶内filter
- 学习桶内filter之前,先看看官方的布尔查询DSL,如下所示,查询JSON对象的内部可以加入filter,对查询结果做过滤:
GET /_search
{
“query”: {
“bool”: {
“must”: [ —布尔查询
{ “match”: { “title”: “Search” }},
{ “match”: { “content”: “Elasticsearch” }}
],
“filter”: [ —对查询结果做过滤
{ “term”: { “status”: “published” }},
{ “range”: { “publish_date”: { “gte”: “2015-01-01” }}}
]
}
}
}
桶内filter和布尔查询中的filter类似,对进入桶中的数据可以加入filter,这样桶内的数据就是此filter过滤后的数据了;
2. 举个例子,统计蓝色的福特汽车销售额,首先限定品牌范围,这个可以直接用之前的限定方式,然后在桶内加入一个filter,只保留颜色为蓝色的文档:
GET /cars/transactions/_search
{
“size”: 0,
“query”: {
“bool”: { —布尔查询,里面可以将query和filter组合使用
“filter”: { —本例只用到了filter
“term”: { —精确匹配
“make”: “ford” —匹配福特品牌
}
}
}
},
“aggs”: {
“sales”: {
“filter”: { —桶内filter
“term”: { —精确匹配
“color”: “blue” —匹配蓝色
}
},
“aggs”: {
“blue_sales”: {
“sum”: { —metrics操作,累加
“field”: “price”
}
}
}
}
}
}
返回结果如下,可见hits.total等于2,表示查询到了两个文档,但是sales.doc_count等于1,表示桶内filter作用后再桶内只剩下一个文档了:
“hits” : {
“total” : 2,
“max_score” : 0.0,
“hits” : [ ]
},
“aggregations” : {
“sales” : {
“doc_count” : 1,
“green_sales” : {
“value” : 25000.0
}
}
}
}
[](()后过滤器(post_filter)
还有一种特殊的filter,名为post_filter,其作用描述如下:
正常的聚合:先查询,得到查询结果A,再用A做聚合操作得到结果B,最后返回B和A;