ES-分组聚合

返回空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. 如果是过滤桶的话, 只聚合满足过滤条件的数据.

提示. 过滤器非常有用因为他们比简单的查询更快(不进行文档评分)并且会自动缓存.

猜你喜欢

转载自blog.csdn.net/yangsnow_rain_wind/article/details/80913615