elasticsearch 聚合查询原理

初恋的背后 15天前   阅读数 30 0

1. ES聚合查询概念

每个聚合都是一个或者多个和零个或者多个指标的组合

SELECT COUNT(color) ①

FROM table

GROUP BY color      ②

COUNT(color)相当于指标,GROUP BY color相当于桶。

桶在概念上类似于 SQL 的分组(GROUP BY),而指标则类似于 COUNT() 、 SUM() 、 MAX() 等统计方法。

ElasticSearch 里面桶的叫法和 SQL 里面分组的概念是类似的,一个桶就类似 SQL 里面的一个 group,多级嵌套的 aggregation, 类似 SQL 里面的多字段分组(group by field1,field2, …..),注意这里仅仅是概念类似,底层的实现原理是不一样的。

2. ES聚合执行机制(Execution hint)

什么是Ordinals?

什么是全局序号Global Ordinals?

Global Ordinals分布在索引的所有段segment中,所以如果新增或删除一个分段时,需要对全局序号进行重建。 重建需要读取每个分段的每个唯一项,基数越高(即存在更多的唯一项)这个过程会越长。Global Ordinals是构建在内存 fielddata 和 doc values 之上的。实际上,它们正是 doc values 性能表现不错的一个主要原因。

Ordinals的构建只被应用于字符串。数值信息(integers(整数)、geopoints(地理经纬度)、dates(日期)等等)不需要使用Ordinals映射,因为这些值自己本质上就是Ordinals映射。

Global Ordinals在遇到High Cardinality(Large Number of Unique Values,即某个字段的值有很多很多种,可以理解为count distinct这个字段的数值大小)的情况下,聚合效率低。

execution_hint设置

map:为了在每个桶中聚合数据,直接使用field values,当只有很少文档能够匹配查询的时候使用(返回结果集合比较小的时候适用)

global_ordinals:使用field的ordinals,预先为每个ordinal value分配一个桶,默认用于top-level terms aggregations,不适合于多个嵌套aggregations

global_ordinals_hash:使用field的ordinals,动态为每个ordinal value分配一个桶,默认用于inner aggregations

global_ordinals_low_cardinality:通过使用每个segment ordinals来计算count,使用global ordinals来重新map这些count到global counts,应用于leaf terms aggregations,内存开销和字段非重复值的个数线性相关,默认用于low-cardinality fields 字段的值种类很少的情况

例子:

{

    "aggs" : {

        "tags" : {

             "terms" : {

                 "field" : "tags",

                 "size" : 5,              返回top 5 terms的聚合结果,值越大开销越大

                  "collect_mode" : "breadth_first"  广度优先

                 "execution_hint": "map"

             }

         }

    }

}

ES聚合查询步骤

以下内容来源于ES中文社区帖子内容

 

Git issue

git上有一个issue:过滤加聚合,过滤后匹配的数据即使是0,对于高cardinality的字段进行聚合,依旧十分耗时

ES官方博客提升聚合查询小tip

https://www.elastic.co/cn/blog/improving-the-performance-of-high-cardinality-terms-aggregations-in-elasticsearch

 


注意:本文归作者所有,未经作者允许,不得转载

全部评论: 0

    我有话说: