前置知识
- DSL 结构:
query先筛选文档 →aggs做统计;size:0不返回原始文档 - 字段类型:
- 指标聚合:
int/double/long数值字段 - terms 分组:必须
keyword,text 不能直接分组
- 指标聚合:
- 两个概念区分
- Metric:对文档算值(sum/avg/min/max/stats/cardinality/value_count)
- Bucket:把文档分到不同桶(分组)(terms、date_histogram、range、filter、missing)
Metric 指标聚合
只算统计值,不分桶。
1、value_count
统计该字段有值的个数,多值字段会统计每一个值,不是只算文档 1 次。可以直接使用的类型:数值类、日期类、布尔、IP、地理,text默认不能直接跑 value_count。
注意:
- null / 不存在字段 → 不计入
文档存在,但price:null或者文档没有 price 字段 → value_count 不计数。 - 多值字段(数组)
例如tags: ["a","b"],这条文档会贡献2到 value_count,不是 1!
例如:查看price不为空的个数
2、min/max/sum/avg 单独指标
单独计算最小值、最大值、和及平均数。
3、stats展示所有指标
显示:数量、最大、最小、和、平均数
4、cardinality
近似去重 count,近似值,不是精确统计。
Bucket 桶聚合
类似于mysql中的group by,对查询结果进行分桶。桶聚合产出多个桶,每个桶里有一批文档,桶可以嵌套子聚合。
1、terms-按指定字段分桶
按指定字段分桶,按字段原始精确值分组,要求字段生成「词条」,默认不能直接对 text 分词字段做 terms。
按商品类型进行分桶:
2、date_histogram-按固定时间间隔分桶
按时间分桶,作用于date/date_nanos类型字段,有两种区间:
- calendar_interval 日历区间(推荐自然时间)
自动适配日历规则:月份天数不同、闰年、夏令时
可选值:year/quarter/month/week/day/hour/minute/second - fixed_interval 固定毫秒时长
固定时长,一天永远 = 24h,不受月份、夏令时影响
单位:ms毫秒、s秒、m分、h小时、d天
参数列表:
| 参数 | 说明 |
|---|---|
field | 必填,必须是 date 类型字段(例如product 表:createtime) |
calendar_interval/fixed_interval | 二选一,时间粒度 |
format | 格式化 key_as_string,yyyy-MM-dd,方便前端展示 |
min_doc_count | 桶内最少文档数。默认 1;设 0:没有数据的时间段也返回桶,count=0(时序图表必备) |
time_zone | 时区,ES 内部存 UTC;中国时区写+08:00或Asia/Shanghai,分桶按北京时间 |
extended_bounds | 扩展时间范围,强制生成起止区间内的空桶(不是过滤!过滤写在 query 里) |
offset | 时间偏移,微调桶起始点,例如+8h |
按创建日期分桶
创建时间,按月分桶
3、range-按自定义返回分桶
按指定范围分桶,支持数值(range)及日期类型(date_range),方便自定义桶区间。[from,to)
按价格区间分桶:(−∞-\infty−∞,1000)、[1000,5000)、[5000,+∞+\infty+∞):
按日期区间:
4、missing-按缺失字段分桶
统计【某个字段缺失】的文档,全部放到单独一个桶里,文档中没有这个字段或字段值为null。字符串“”不能算缺失。
新增一条没有lv字段的文档,查询缺失lv数据。
嵌套子聚合
聚合查询支持嵌套,在哪个桶下面嵌套,就在对应的桶名称里面写aggs。
按type分桶后再按lv分桶:
按type分桶后再按lv分桶,再统计每个桶内的价格指标:
Pipeline 管道聚合
管道聚合不是直接扫描原始文档,而是拿【前面桶聚合的结果】做二次计算。
两类:
- Sibling 兄弟管道聚合:和目标聚合平级,输出单独结果,不修改原桶。比如
stats_bucket、sum_bucket、avg_bucket - Parent 父管道聚合:写在父聚合内部,改造原有桶,往桶里新增计算字段。比如
derivative(导数 / 环比)、moving_avg(移动平均)、cumulative_sum(累计求和)
1、Parent 父管道聚合
1、cumulative_sum-累计求和
再分桶结果中添加累计和。
2、derivative 导数
计算当前桶 - 上一个桶,适合看环比增长量
3、moving_fn /moving_avg 移动平均
滑动窗口,取最近 N 个桶平均值,平滑时序曲线。
创建时间按月分桶,计算每个桶的总价,添加最近3个桶的平均值
4、bucket_selector 桶选择器
只保留符合条件的桶,不满足条件的桶直接剔除
注意:只是过滤聚合结果,不会过滤原始文档
示例:只保留月总价格 >4000 的月份桶
5、bucket_sort 桶排序
对已经分好的 buckets 排序、截取 topN,不是原始文档排序
示例:按商品类别分桶,按总价降序,取前二
2、Sibling 兄弟管道聚合
放在和上游桶聚合同一级,不是写在桶里面。
1、sum_bucket:所有桶的指标总和
示例:按月分桶,每个月 sum 价格;再用 sum_bucket 求全部月份总和
2、avg_bucket / max_bucket / min_bucket / stats_bucket /
用法完全一样:
avg_bucket:所有桶指标的平均值max_bucket:找出指标最大的桶,返回 key 和 valuemin_bucket:找出指标最小的桶stats_bucket:一次性返回 sum、avg、min、max、count
示例:找出总价最高的产品类别