聚合分析
官方文档https://www.elastic.co/guide/en/elasticsearch/reference/current/search-aggregations.html
- 英文为 Aggregation,是 es 除搜索功能为提供的针对 es数据做统计分析的功能
- 功能丰富,提供Bucket,Metric、Pipeline等多种分析方式,可以满足大部分的分析需求
- 实时新高,所有的计算结果都是即时返回的,而Hadoop的大数据系统一般都是T+1级别的
聚合分析作为 search的一部分,api如下所示:
- 请告诉我公司目前在职人员工作岗位的分布情况?
分类
- 为了比那与理解,es将聚合分析主要分为如下4类
- Bucket, 分桶类型,类似SQL中的GROUP BY 语法
- Metric, 指标分析类型,如计算最大值,最小值,平均值等等
- Pipeline,管道分析类型,基于上一级的聚合分析结果进行再分析
- Matrix, 矩阵分析类型
Metric
- 主要分如下两类:
- 单值分析,只输出一个分析结果
- min,max,avg,sum
- cardinality
- 多值分析,输出多个分析结果
- stats,extended stats
- percentile,percentile rank
- top hits
Min
- 返回数值类字段的最小值
Max
- 返回数值类字段的最大值
Avg
- 返回数值类字段的平均值
Sum
- 返回数值类型字段的总和
Metric 聚合分析
- 一次返回多个聚合结果
Cardinality
- Cardinality,意为集合的势,或者基数,是指不同数值的个数,类似SQL中的distinct count概念
Stats
- 返回一系列数值类型的统计值,包含min、max、avg、sum和count
Extended Stats
- 对stats的扩展,包含了更多的统计数据,比如方差,标准差等
Percentile
- 百分位数统计
- 百分数 values “1.0”:5150 -> 5150 所占的百分率
- - 百分位数统计
- 11000,30000所占的比例。
Top Hits
- 一般用于分桶后获取该桶内最匹配的顶部文档列表,即详情数据
Bucket 聚合分析
- Bucket,意为桶,即按照一定的规则将文档分配到不同的桶中,达到分类分析的目的
- 按照Bucket的分桶策略,常见的Bucket聚合分析如下:
- Terms
- Range
- Date Range
- Histogram
- Date Histogram
Bucket 聚合分析 - Term
- 该分桶策略最简单,直接按照term来分桶,如果是text类型,则按照分词后的结果分词
Bucket 聚合分析 - Range
- 通过指定数值的范围来设定分桶规则
Bucket 聚合分析 - Date Range
- 通过日期指定日期的范围来设定分桶规则
Bucket 聚合分析 - Historgram
- 直方图,以固定间隔的策略来分割数据
Bucket 聚合分析 - Date Historgram
- 针对日期的直方图或者柱状图,是时序数据分析中常用的聚合分析类型
Bucket + Metric 聚合分析
- Bucket 聚合分析允许通过添加子分析来进一步进行分析,该子分析可以是 Bucket也可以是Metric(可以不断嵌套)。这也使得es的聚合分析能力变得异常强大。
分桶之后再分桶
- 分桶后进行数据分析
Pipeline 聚合分析
- 针对聚合分析的结果再次进行聚合分析,而且支持链式调用,可以回答如下问题:
- 订单月平均销售额是多少?
- Pipeline 的分析结果会输出到原结果中,根据输出位置的不同,分为以下两类:
- Parent 结果内嵌到现有的聚合分析结果中
- Derivative (导数)
- Moving Average (移动求和)
- Cumulative Sum (累计求和)
- Sibling 结果与现有聚合分析结果统计
- Max/Min/Avg/Sum Bucket
- Stats/Extended Stats Bucket
- Percentiles Bucket
Pipeline 聚合分析 Sibling - Min Bucket
Pipeline 聚合分析 Sibling - Max Bucket
- 找出所有 Bucket中值最大的 Bucket 名称和值
Pipeline 聚合分析 Sibling - Avg Bucket
- 计算所有 Bucket的平均值
Pipeline 聚合分析 Sibling - Sum Bucket
- 计算所有 Bucket值的总和
Pipeline 聚合分析 Sibling - Stats Bucket
- 计算所有 Bucket值的Stats分析
Pipeline 聚合分析 Sibling - Percentiles Bucket
- 计算所有 Bucket值的百分位数
Pipeline 聚合分析 Parent - Derivative
- 计算 Bucket值的导数
Pipeline 聚合分析 Parent - Moving Average
- 计算 Bucket值的移动平均值
Pipeline 聚合分析 Parent - Cumulative Sum
- 计算 Bucket值的累计加和
作用范围
- es聚合分析默认作用范围是query的结果集,可以通过如下的方式改变其作用范围:
- fileter
- post_filter
- global
- aggs 聚合分析值分析query结果的数据
作用范围 - filter
- 为摸个聚合分析设定过滤条件,从而在不变更整体 query语句的情况下修改了作用范围
作用范围 - post-filter
- 作用于文档过滤,但在聚合分析后生效
作用范围 - global
- 无视 query 过滤条件,基于全部文档进行分析
排序
- 可以使用自带的关键词数据进行排序,比如:
- _count文档数
- _key 按照 key 值排序 - 按照子聚合中的结果排序
- 先按年龄分桶
- 在计算每个桶中平均值
- 按照每个桶的平均值来排序
计算精准度问题
Min 聚合的执行流程
Trems 集合执行流程
Terms 并不永远准确
Terms 不准确的原因
- 数据分散在多 Shard 上,Coordinating Node 无法得悉数据全貌
Terms 不准确的解决方法
- 设置 Shard 数为1,消除数据分散的问题,但无法承载大数据量
- 合理设置 Shard_Size 大小,级每次从 Shard上额外获取数据,以提升准确度
Shard_Size 大小的设定方法 - terms 聚合返回结果中有如下两个统计值:
- doc_count_error_upper_bound 被遗漏 term可能的最大值
- sum_other_doc_count 返回结果 bucket的 term外其他 term的文档总数
- 设定 show_term_doc_count_errror可以查看每个 bucket误算的最大值,(每个shard都返回时为0)
Shard_Size 大小的设定方法 - term(d)不是每个 shard都有,取其他没有此 term(d)的 shard 中的最小值(如下的 b(2))相加得到show_term_doc_count_errror。 所以每个shard都有term的话(如 term a、 b),将返回为0。
- Shard_Size 默认大小如下:
- shard_size = (size * 1.5) + 10 - 通过调整 Shard_Size的大小减低 show_term_doc_count_errror来提供准确度
- 增大了整体的计算量,从而降低了相应时间
近似统计算法
- 在ES的聚合分析中,Cardinality 和 Percentile 分析实验的是近似算法
- 结果是近似准确的,但不一定精准
- 可以通过参数的调整时期结果精确,但同时也意为着更多的计算时间和更大的性能消耗