ElasticSearch中的聚合查询

ES中主要有如下几种聚合方式。

1、Bucket,分桶类型,有点类似于SQL中的GROUP BY语法

2、Metric,指标分析类型,如计算平均值、最小值、最大值等

3、Pipeline,管道分析类型,基于上一级的分析结果进行再分析

4、Matrix,矩阵分析类型。

本文主要介绍Buckets(桶)和Metrics(指标)两种聚合方式

桶(Buckets)

它表示满足特定条件的文档的集合。就是说将ES中的数据按照某种条件进行划分,比如一个用户按照户籍所在地进行划分,可以分为北京桶天津桶上海桶武汉桶等等,或者按照性别进行划分,可以分为男性桶女性桶

ElasticSearch中提供的划分桶的方式有很多:

Date Histogram Aggregation:根据日期阶梯分组,例如给定阶梯为周,会自动每周分为一组

Histogram Aggregation:根据数值阶梯分组,与日期类似

Terms Aggregation:根据词条内容分组,词条内容完全匹配的为一组

Range Aggregation:数值和日期的范围分组,指定开始和结束,然后按段分组

……

指标(Metrics)

它表示对桶内的文档进行统计计算。如计算最小值平均值最大值,还有汇总等。在实践中,指标能让你计算像平均薪资、最高出售价格、95%的查询延迟这样的数据。

比较常用的一些度量聚合方式主要分为如下两类:

单值分析,只输出一个分析结果

min, max, avg, sum

cardinality 表示集合的势,或者基数,是指不同数值的个数,类似SQL中的distinct count概念

多值分析,输出多个分析结果

stats, extended stats

percentile, percentile rank

top hits

开始尝试聚合

引用官网的示例

POST /cars/transactions/_bulk
{ "index": {}}
{ "price" : 10000, "color" : "red", "make" : "honda", "sold" : "2014-10-28" }
{ "index": {}}
{ "price" : 20000, "color" : "red", "make" : "honda", "sold" : "2014-11-05" }
{ "index": {}}
{ "price" : 30000, "color" : "green", "make" : "ford", "sold" : "2014-05-18" }
{ "index": {}}
{ "price" : 15000, "color" : "blue", "make" : "toyota", "sold" : "2014-07-02" }
{ "index": {}}
{ "price" : 12000, "color" : "green", "make" : "toyota", "sold" : "2014-08-19" }
{ "index": {}}
{ "price" : 20000, "color" : "red", "make" : "honda", "sold" : "2014-11-05" }
{ "index": {}}
{ "price" : 80000, "color" : "red", "make" : "bmw", "sold" : "2014-01-01" }
{ "index": {}}
{ "price" : 25000, "color" : "blue", "make" : "ford", "sold" : "2014-02-12" }

比如要找出那个颜色汽车的销量好,可以用terms操作

GET /cars/transactions/_search
{
  "size": 0,
  "aggs": {
    "popular_color": {
      "terms": {
        "field": "color"
      }
    }
  }
}
  • size:查询条数,这里设置为0表示不展示查询到的数据,因为我只想看到聚合的结果,同时也节省效率。
  • aggs:聚合查询
    • popular_color:聚合结果的自定义字段
    • terms:划分桶的方式,这里是根据词条划分
      • field:划分桶的字段

查询结果

{
...
   "hits": {
      "hits": [] 
   },
   "aggregations": {
      "popular_colors": { 
         "buckets": [
            {
               "key": "red", 
               "doc_count": 4 
            },
            {
               "key": "blue",
               "doc_count": 2
            },
            {
               "key": "green",
               "doc_count": 2
            }
         ]
      }
   }
}
  • popular_colors:聚合的自定义返回的字段
    • buckets:聚合桶,里面为聚合的集合
    • doc_count:文档数量

更进一步,如果还想知道每个颜色汽车销售的平均价格,仅依靠上面的统计无法得到结果,还需要为其添加度量指标。所以这里用到了平均值的度量指标。

GET /cars/transactions/_search
{
  "size": 0,
  "aggs": {
    "popular_color": {
      "terms": {
        "field": "color"
      },
      "aggs": {
        "avg_price": {
          "avg": {
            "field": "price"
          }
        }
      }
    }
  }
}

popular_color中再嵌套一层aggs聚合,给这个内部聚合再起一个名字为avg_price(这个名字随意起),然后使用avg这个度量指标去度量,指定要度量的字段为price

{
...
   "aggregations": {
      "popular_color": {
         "buckets": [
            {
               "key": "red",
               "doc_count": 4,
               "avg_price": { 
                  "value": 32500
               }
            },
            {
               "key": "blue",
               "doc_count": 2,
               "avg_price": {
                  "value": 20000
               }
            },
            {
               "key": "green",
               "doc_count": 2,
               "avg_price": {
                  "value": 21000
               }
            }
         ]
      }
   }
...
}

可以看到在原来的每一条数据中有嵌套了一层avg_price,这正是内部聚合得到的统计结果。

这里只讲到了Terms这种聚合方式,还有其它很多种聚合方式,更详细的内容参见官方文档

如果您觉得本文对您有用,欢迎捐赠或留言~
微信支付
支付宝

发表评论

您的邮箱地址不会被公开。 必填项已用 * 标注