返回空Buckets
GET /cars/transactions/_search
{
"size" : 0,
"aggs": {
"sales": {
"date_histogram": {
"field": "sold",
"interval": "month",
"format": "yyyy-MM-dd",
"min_doc_count" : 0, //这个参数强制返回空 buckets。
"extended_bounds" : { //这个参数强制返回整年。
"min" : "2014-01-01",
"max" : "2014-12-31"
}
}
}
}
}
这两个参数会强制返回一年中所有月份的结果,而不考虑结果中的文档数目。 min_doc_count 非常容易理解:它强制返回所有 buckets,即使 buckets 可能为空。
extended_bounds 参数需要一点解释。 min_doc_count 参数强制返回空 buckets,但是 Elasticsearch 默认只返回你的数据中最小值和最大值之间的 buckets。
我们构建聚合以便按季度展示所有汽车品牌总销售额。同时按季度、按每个汽车品牌计算销售总额,以便可以找出哪种品牌最赚钱:
GET /cars/transactions/_search
{
"size" : 0,
"aggs": {
"sales": {
"date_histogram": {
"field": "sold",
"interval": "quarter", //注意我们把时间间隔从 month 改成了 quarter 。
"format": "yyyy-MM-dd",
"min_doc_count" : 0,
"extended_bounds" : {
"min" : "2014-01-01",
"max" : "2014-12-31"
}
},
"aggs": {
"per_make_sum": {
"terms": {
"field": "make"
},
"aggs": {
"sum_price": {
"sum": { "field": "price" } //计算每种品牌的总销售金额。
}
}
},
"total_sum": {
"sum": { "field": "price" } //每个季度中全部品牌的汇总销售金额。
}
}
}
}
}
返回结果如下:
....
"aggregations": {
"sales": {
"buckets": [
{
"key_as_string": "2014-01-01",
"key": 1388534400000,
"doc_count": 4,
"per_make_sum": {
"doc_count_error_upper_bound": 0,
"sum_other_doc_count": 0,
"buckets": [
{
"key": "bmw",
"doc_count": 2,
"sum_price": {
"value": 160000
}
},
{
"key": "ford",
"doc_count": 2,
"sum_price": {
"value": 50000
}
}
]
},
"total_sum": {
"value": 210000
}
},
....
聚合是基于我们查询匹配的文档集合进行计算的, 当查询中没有查询条件时, ES默认查询所有文档.
全局 桶包含 所有 的文档,它无视查询的范围。因为它还是一个桶,我们可以像平常一样将聚合嵌套在内:
GET /cars/transactions/_search
{
"size" : 0,
"query" : {
"match" : {
"make" : "ford"
}
},
"aggs" : {
"single_avg_price": {
"avg" : { "field" : "price" } //聚合操作在查询范围内(所有文档匹配 ford )
},
"all": {
"global" : {}, //global 全局桶没有参数。
"aggs" : {
"avg_price": {
"avg" : { "field" : "price" } //聚合操作针对所有文档,忽略汽车品牌。
}
}
}
}
}
single_avg_price 度量计算是基于查询范围内所有文档,即所有 福特 汽车。
avg_price 度量是嵌套在全局桶下的,这意味着它完全忽略了范围并对所有文档进行计算。返回所有汽车的平均售价。
因为聚合是在查询结果范围内操作的,任何可以适用于查询的过滤器也可以应用在聚合上。
GET /cars/transactions/_search
{
"size" : 0,
"query" : {
"constant_score": {
"filter": {
"range": {
"price": {
"gte": 10000
}
}
}
}
},
"aggs" : {
"single_avg_price": {
"avg" : { "field" : "price" }
}
}
}
查询(包括了一个过滤器)返回一组文档的子集,聚合正是操作这些文档。使用 filtering query 会忽略评分,并有可能会缓存结果数据等等。
GET /cars/transactions/_search
{
"query":{
"match": {
"make": "ford"
}
},
"aggs":{
"recent_sales": {
"filter": { //此处为过滤桶, 只有满足过滤条件的数据才会被聚合
"term": {
"color": "blue"
}
},
"aggs": {
"sum_price":{
"sum": {
"field": "price"
}
}
}
}
}
}
执行逻辑:
1. 首先执行query, 获取所有doc, 然后遍历doc, 再进行聚合,
2. 如果是过滤桶的话, 只聚合满足过滤条件的数据.
提示. 过滤器非常有用因为他们比简单的查询更快(不进行文档评分)并且会自动缓存.