1、数据聚合
聚合(aggregations)可以让我们极其方便的实现数据的统计、分析和运算。实现这些统计功能的比数据库的 SQL 要方便的多,而且查询速度非常快,可以实现近实时搜索效果。
注意: 参加聚合的字段必须是 keyword、日期、数值和布尔类型
1.1 聚合的种类
常见的聚合类型:
1.1.1 桶聚合(Bucket):对文档分组,类似 MySQL的 group by 功能
类型 | 描述 |
---|---|
TermAggregation | 按照文档字段值分组,如:品牌分组 |
Date Histogram | 按照日期阶梯分组,如:按月分组 |
1.1.2 度量聚合(Metric):值计算,如:最大值、最小值、平均值等等
类型 | 描述 |
---|---|
Avg | 求平均值 |
Max | 求最大值 |
Min | 求最小值 |
Stats | 同时求max、min、avg、sum等 |
1.1.3 管道聚合(pipeline): 对已聚合的结果为基础做聚合
1.2 聚合示例测试1
需求:从所有酒店数据中,查询酒店金额不大于300的所有酒店品牌的种类,并按照品牌的数量进行逆序排序,筛选出前5个数量最多的品牌。
分析:① 限制酒店金额 ② 根据酒店的品牌做聚合(Bucket)查询 ③ 逆序排序
1.2.1 定义 DSL 语法
GET /hotel/_search
{"query": {"range": {"price": {"lte": 300}}},"size": 0,"aggs": {"brandAggs": {"terms": {"field": "brand","size": 5,"order": {"_count": "desc"}}}}
}
1.2.2 参数说明
- size: 设置为0,结果中不需要包含文档,只返回聚合结果
- aggs:定义聚合,固定值
- brandAgg:聚合名称,自定义语义化即可
- terms: 聚合类型,brand 是一个 keyword 类型的字符串,所以用 terms
- field:参与聚合的字段
- size:希望获取的聚合结果数量
- order:指定排序,按照 _count 逆序排序
- brandAgg:聚合名称,自定义语义化即可
1.2.3 测试结果
1.3 聚合示例测试2
需求: 对酒店的品牌分组,并计算每个品牌的用户评分的最大值、最小值和平均值等,并按照酒店评分的平均值逆序排序
分析:① 对品牌进行桶(Bucket)聚合 ② 对桶聚合的结果进行(Metric)聚合运算
1.3.1 定义 DSL 语法
GET /hotel/_search
{"size": 0,"aggs": {"brandAgg": {"terms": {"field": "brand","size": 10,"order": {"scoreAgg.avg": "desc"}},"aggs": {"scoreAgg": {"stats": {"field": "score"}}}}}
}
1.3.2 参数说明
- size: 设置为0,结果中不需要包含文档,只返回聚合结果
- aggs:定义聚合,固定值
- brandAgg:聚合名称,自定义语义化即可
- terms: 聚合类型,brand 是一个 keyword 类型的字符串,所以用 terms
- field:参与聚合的字段
- size:希望获取的聚合结果数量
- order:指定排序,这里按照 “scoreAgg.avg” 逆序排序
- terms: 聚合类型,brand 是一个 keyword 类型的字符串,所以用 terms
- aggs:对 brandAggs 的子聚合,也就是说多聚合后的结果分别计算,固定值
- scoreAgg:聚合名称,自定义语义化即可
- stats:Metric 聚合计算,这里的 stats 可以计算 min、max、avg、sum的值
- field:聚合字段
- scoreAgg:聚合名称,自定义语义化即可
- brandAgg:聚合名称,自定义语义化即可
1.3.3 测试结果
1.4 聚合示例测试3
需求:对酒店的品牌分组,累加品牌评分,按累计评分逆序排序,筛选出前5名,计算每个品牌评分占总评分的比率
分析:① 对品牌进行桶(Bucket)聚合 ② 对桶聚合的结果进行(Metric)聚合运算 ③ 聚合计算(Pipeline)④ 逻辑运算
1.4.1 定义 DSL 语法
GET /hotel/_search
{"size": 0,"aggs": {"brandAgg": {"terms": {"field": "brand","size": 5,"order": {"singleBrandTotalScore": "desc"}},"aggs": {"singleBrandTotalScore": {"sum": {"field": "score"}}}},"allBrandTotalScore": {"sum_bucket": {"buckets_path": "brandAgg>singleBrandTotalScore"}}}
}
1.4.2 参数说明
- size: 设置为0,结果中不需要包含文档,只返回聚合结果
- aggs:定义聚合,固定值
-
brandAgg:聚合名称,自定义语义化即可
- terms: 聚合类型,brand 是一个 keyword 类型的字符串,所以用 terms
- field:参与聚合的字段
- size:希望获取的聚合结果数量
- order:指定排序,这里按照 “singleBrandTotalScore.value” 逆序排序,sum 聚合运算 value 可省略
- terms: 聚合类型,brand 是一个 keyword 类型的字符串,所以用 terms
-
aggs:对 brandAggs 的子聚合,也就是说多聚合后的结果分别计算,固定值
- singleBrandTotalScore: 多单一品牌的所有评分进行累加
- sum: 对 score 字段求和
- singleBrandTotalScore: 多单一品牌的所有评分进行累加
-
allBrandTotalScore:聚合名称,自定义语义化即可,每个品牌的得分总和再次求和,以获得所有品牌的总得分
- sum_bucket: 管道聚合
- buckets_path:指定了数据来源路径,即来自brandAgg聚合中 singleBrandTotalScore 的结果
- sum_bucket: 管道聚合
-