第07章-聚合分析
# 一、聚合分析概述
搜索引擎用来回答如下问题:
- 请告诉我地址为上海的所有订单?
- 请告诉我最近 1 天内创建但没有付款的所有订单?
聚合分析可以回答如下问题:
- 请告诉我最近 1 周每天的订单成交量有多少?
- 请告诉我最近 1 个月每天的平均订单金额是多少?
- 请告诉我最近半年卖的最火的前 5 个商品是哪些?
聚合分析(Aggregation),是 es 除搜索功能外提供的针对 es 数据做统计分析的功能
- 功能丰富,提供 Bucket、Metric、Pipeline 等多种分析方式,可以满足大部分的分析需求
- 实时性高,所有的计算结果都是即时返回的,而 hadoop 等大数据系统一般都是 T+1 级别的
聚合分析作为 search 的一部分,api 如下所示:
例:请告诉我公司目前在职人员工作岗位的分布情况?
为了便于理解,es 将聚合分析主要分为如下 3 类
- Bucket:分桶类型,类似 SQL 中的 GROUP BY 语法
- Metric:指标分析类型,如计算最大值、最小值、平均值等等
- Pipeline:管道分析类型,基于上一级的聚合分析结果进行再分析
具体参考官方文档:Aggregations (opens new window)
# 二、Metric 聚合分析
主要分如下两类:
- 单值分析,只输出一个分析结果
- min,max,avg,sum
- cardinality
- 多值分析,输出多个分析结果
- stats,extended stats
- percentile,percentile rank
- top hits
# 2.1 单值分析
# 2.1.1 min
单值分析以 min 为例,返回数值类字段的最小值,max、avg、sum 同理。
一次返回多个聚合分析:
# 2.1.2 cardinality
Cardinality,意为集合的势,或者基数,是指不同数值的个数,类似 SQL 中的 distinct count 概念。
# 2.2 多值分析
# 2.2.1 stats
返回一系列数值类型的统计值,包含 min、max、avg、sum 和 count。
# 2.2.2 extended stats
对 stats 的扩展,包含了更多的统计数据,如方差、标准差等。
# 2.2.3 percentile
返回指定字段的各百分位数档次统计。
以上响应表示,1.0%的数据在5150以内,95.5%的数据在26250以内。
# 2.2.4 percentile rank
返回指定字段指定值所处的百分位。
以上示例表示,11000 工资在 50% 的位置,30000 工资在 75% 的位置。
# 2.2.5 top hit
一般用于分桶后获取该桶内最匹配的顶部文档列表,即详情数据。
上述请求表示,现根据 job 名称分组,然后对每个 job 组中的数据取年龄在前 10 名的,根据年龄倒序排列。(就像是公司裁员,每个岗位取 10 个年纪最大的,干掉)
# 三、Bucket 聚合分析
Bucket,意为桶,即按照一定的规则将文档分配到不同的桶中,达到分类分析的目的。
按照 Bucket 的分桶策略,常见的 Bucket 聚合分析如下:
- Terms
- Range
- Date Range
- Histogram
- Date Histogram
# 3.1 分桶策略
# 3.1.1 Terms 单词分桶
该分桶策略最简单,直接按照 term 来分桶,如果是 text 类型,则按照分词后的结果分桶
# 3.1.2 Range 范围分桶
通过指定数值的范围来设定分桶规则
# 3.1.3 Date Range 时间范围分桶
通过指定日期的范围来设定分桶规则
# 3.1.4 Histogram 固定间隔分桶
直方图,以固定间隔的策略来分割数据
# 3.1.5 Date Histogram 固定日期间隔分桶
针对日期的直方图或者柱状图,是时序数据分析中常用的聚合分析类型
# 3.2 Bucket + Metric 聚合分析
Bucket 聚合分析允许通过添加子分析来进一步进行分析,该子分析可以是 Bucket 也可以是 Metric。这也使得 es 的聚合分析能力变得异常强大
例一:分桶后再分桶
例二:分桶后进行数据分析
# 四、Pipeline 聚合分析
# 4.1 Pipeline 聚合介绍
针对聚合分析的结果再次进行聚合分析,而且支持链式调用。
可以回答如下问题:订单月平均销售额是多少?
上述聚合示例有3步
- 根据月份分桶,分到每个月份的营业额集合(
sales_per_month
) - 对分桶的结果进行求和分析,计算出每个月的营业总额(
sales
) - 对每月的营业总额求平均值(
avg_monthly_sales
,分析的是sales_per_month
>sales
下的结果)
Pipeline 的分析结果会输出到原结果中,根据输出位置的不同,分为以下两类:
- Sibling:结果与现有聚合分析结果同级
- Parent:结果内嵌到现有的聚合分析结果中
# 4.2 Pipeline 聚合分类
# 4.2.1 Sibling Pipeline
Sibling Pipeline 聚合结果与现有聚合分析结果同级,有以下几种聚合方式:
聚合方式 | 作用 |
---|---|
max_bucket min_bucket avg_bucket sum_bucket | 求最值、平均值、求和 |
stats_bucket extended_stats_bucket | 一系列统计数 |
percentiles_bucket | 百分位数统计 |
# min_bucket
找出所有 Bucket 中值最小的 Bucket 名称和值
以上示例表示:按 job 类型分组,求出每种 job 的平均工资,同时得出平均工资最少的一个桶
注意:这里请求的聚合名里,
avg_salary
在jobs
里面,而min_salary_by_job
和外层的jobs
同级
min_bucket、avg_bucket、sun_bucket 用法类似
# stats_bucket
计算所有 Bucket 值的 Stats 分析
# percentiles_bucket
计算所有 Bucket 值的百分位数
# 4.2.2 Parent Pipeline
Parent Pipeline 聚合结果内嵌到现有的聚合分析结果中,有以下几种方式:
聚合方式 | 作用 |
---|---|
derivative | 导数 |
moving_avg | 移动平均值 |
cumulative_sum | 累积加和 |
# derivative
计算Bucket值的导数
注意:这里请求的聚合名里,
avg_salary
在birth
里面,而derivative_avg_salary
和内层的avg_salary
同级,也在birth
里面
moving_avg、cumulative_sum 用法类似
# 五、作用范围
es 聚合分析默认作用范围是 query 的结果集,可以通过如下的方式改变其作用范围
- filter:基于主查询聚合分析
- post_filter:聚合分析之后影响主查询
- global:无视主查询,聚合分析所有文档
# 5.1 filter
为某个聚合分析设定过滤条件,从而在不更改整体 query 语句的情况下修改了作用范围,不影响主查询结果。
上述例子总体有两个聚合分析,jobs_salary_small
和 jobs
,两个聚合分析针对不同的query条件聚合分析。
jobs
根据主查询分析,即没限制查询条件的所有文档。
jobs_salary_small
在主查的基础上,增加了 filter
条件,只分析工资范围是 *-10000
的文档数据。
所以结果 jobs
聚合组有 4 个 bucket,jobs_salary_small
聚合组只有工资少于 10000 的两个 bucket。
# 5.2 post-filter
作用于文档过滤,但在聚合分析后生效,影响主查询结果。
上述示例中,结果是先针对所有文档进行聚合分析,但是得到分析结果之后,会将主查询的 hits
结果按照 post_filter
的规则过滤,所以 jobs
分析的结果中有所有的 bucket,但是主查询 hits
结果中只有一个文档。
# 5.3 global
无视 query 过滤条件,基于全部文档进行分析。
上述示例中,有两个聚合分析,java_avg_salary
和 all
,java_avg_salary
基于主查询 query
进行聚合分析,all
设置 global
,无视主查询的 query 条件,对所有文档进行分析。
# 六、排序
可以使用自带的关键数据进行排序,比如:
_count
文档数_key
按照 key 值排序