ElasticSearch聚合分析:聚合查询(aggs)基本概念

来自Wikioe
跳到导航 跳到搜索


关于

ES 中的聚合查询,类似 SQL 的 SUM / AVG / COUNT / GROUP BY 分组查询,主要用于统计分析场景。

ES聚合查询流程

ES聚合查询类似 SQL 的 GROUP by,一般统计分析主要分为两个步骤:

  1. 分组:对查询的数据首先进行一轮分组,可以设置分组条件;
    例如:新生入学,把所有的学生按专业分班,这个分班的过程就是对学生进行了分组。
  2. 组内聚合:对组内的数据进行统计
    例如:计算总数、求平均值等等,接上面的例子,学生都按专业分班了,那么就可以统计每个班的学生总数,这个统计每个班学生总数的计算,就是组内聚合计算。


分组类似 SQL 的 group by 语句设定的条件。
组内聚合,就是在 select 编写的 avg、sum、count 统计函数;

熟悉SQL语句都知道 sum、count 这些统计函数不一定要跟 group by 语句配合使用,单独使用统计函数等同于将所有数据分成一个组,直接对所有数据进行统计。

核心概念

满足特定条件的文档的集合,叫做

桶的就是一组数据的集合,对数据分组后,得到一组组的数据,就是一个个的桶。


  • 桶等同于组,分桶分组是一个意思,ES 使用桶代表一组相同特征的数据。

ES 中桶聚合,指的就是先对数据进行分组。

ES支持多种分组条件,例如:支持类似 SQL 的 group by 根据字段分组,当然 ES 比 SQL 更强大,支持更多的分组条件,以满足各种统计需求。

指标

指标:指的是对文档进行统计计算的方式,又叫指标聚合


桶内聚合:就是先对数据进行“分组”(分桶),然后对每一个桶内的数据进行“指标聚合”。

说白了就是,前面将数据经过一轮桶聚合,把数据分成一个个的桶之后,我们根据上面计算指标对桶内的数据进行统计。


常用的指标有:SUMCOUNTMAX 等统计函数。


借助SQL的统计语句理解桶和指标:

SELECT COUNT(*) 
FROM order
GROUP BY shop_id

说明:

  • “COUNT(*)”:相当于指标, 也叫统计指标。
  • “GROUP BY shop_id”:相当于分桶的条件,也可以叫分组条件,相同shop_id的数据都分到一个桶内。

这条 SQL 语句的作用就是统计每一个店铺的订单数,所以 SQL 统计的第一步是根据 group by shop_id 这个条件,把 shop_id(店铺ID)相同的数据分到一个组(桶)里面,然后每一组数据使用 count(*) 统计函数(指标)计算总数,最终得到每一个店铺的订单总数,ES 也是类似的过程。

ES聚合查询语法

语法:

{
   "aggregations" : {
      "<aggregation_name>" : {
         "<aggregation_type>" : {
            <aggregation_body>
         }
         [,"aggregations" : { [<sub_aggregation>]+ } ]? // 嵌套聚合查询,支持多层嵌套
      }
      [,"<aggregation_name_2>" : { ... } ]* // 多个聚合查询,每个聚合查询取不同的名字
   }
}

说明:

  • aggregations:代表聚合查询语句,可以简写为 aggs
  • <aggregation_name>:代表一个聚合计算的名字,可以随意命名,因为 ES 支持一次进行多次统计分析查询,后面需要通过这个名字在查询结果中找到我们想要的计算结果;
  • <aggregation_type>:聚合类型,代表我们想要怎么统计数据,主要有两大类聚合类型,桶聚合指标聚合
    • 这两类聚合又包括多种聚合类型,例如:指标聚合:sum、avg, 桶聚合:terms、Date histogram 等等;
  • <aggregation_body>:聚合类型的参数,选择不同的聚合类型,有不同的参数;
  • aggregation_name_2:代表其他聚合计算的名字,意思就是可以一次进行多种类型的统计。


示例:假设存在一个 order 索引,存储了每一笔汽车销售订单,里面包含了汽车颜色字段 color

GET /order/_search
{
    "size" : 0, // 【设置 size=0 的意思就是,仅返回聚合查询结果,不返回普通 query 查询结果】。
    "aggs" : { // 聚合查询语句的简写
        "popular_colors" : { // 给聚合查询取个名字,叫 popular_colors
            "terms" : { // 聚合类型为,terms,【terms是桶聚合的一种】,类似 SQL  group by 的作用,根据字段分组,相同字段值的文档分为一组。
                "field" : "color" // terms聚合类型的参数,这里需要设置分组的字段为 color,根据 color 分组
            }
        }
    }
}

等价SQL:

select count(color) from order group by color

输出:

{
...
   "hits": { // 因为size=0,所以query查询结果为空
      "hits": [] 
   },
   "aggregations": { // 聚合查询结果
      "popular_colors": { // 这个就是 popular_colors 聚合查询的结果,这就是为什么需要给聚合查询取个名字的原因,如果有多个聚合查询,可以通过名字查找结果
         "buckets": [ // 【因为是桶聚合,所以看到返回一个 buckets 数组】,代表分组的统计情况,下面可以看到每一种颜色的销量情况
            {
               "key": "red", 
               "doc_count": 4 // 红色的汽车销量为4
            },
            {
               "key": "blue",
               "doc_count": 2
            },
            {
               "key": "green",
               "doc_count": 2
            }
         ]
      }
   }
}