目录
一、定义
聚合( aggregations)可以实现对文档数据的统计、分析、运算。
二、分类
1、桶(Bucket)聚合:
-
用来对文档做分组
TermAggregation:按照文档字段值分组
Date Histogram:按照日期阶梯分组,例如一周为一组,或者一月为一组
2、度量(Metric)聚合:
- 用以计算一些值,比如:最大值、最小值、平均值等
- 计数(COUNT):计算指定列中非空值的数量。
- 求和(SUM):计算指定列中所有数值的总和。
- 平均值(AVG):计算指定列中所有数值的平均值。
- 最大值(MAX):查找指定列中的最大值。
- 最小值(MIN):查找指定列中的最小值。
3、管道聚合(Pipeline Aggregation):
- 管道聚合是MongoDB中一种强大的数据聚合工具,它可用于通过将多个聚合操作连接在一起来对文档进行处理。
- 通过管道聚合,MongoDB用户可以使用多个聚合操作按顺序执行,以生成更为复杂、细致和灵活的数据查询和汇总结果。
- 管道聚合可以处理来自单个或多个集合的数据。
一般而言,MongoDB 的聚合管道通过 $ 开头的操作符来实现数据聚合操作。以下是一些常见的聚合管道操作:
1. $match:用于选择满足条件的文档,可以通过使用查询条件来过滤文档。
2. $group:用于将文档分组,通过指定一个或多个字段进行分组,对每个分组执行聚合操作,最终返回每个组的统计结果。
3. $project:用于选择文档的特定字段,并输出指定的字段。
4. $sort:用于对文档进行排序,可以根据指定字段进行升序或降序排列。
5. $limit:用于限制输出文档的数量。
6. $skip:用于跳过指定数量的文档,并返回剩余的文档。
7. $unwind:用于展开数组属性,将数组属性的每个元素转换为一个单独的文档。
- 使用管道聚合,可以将以上操作有机地组合在一起,以实现各种复杂的聚合查询需求。
- 此外,MongoDB 还提供了许多其他的聚合管道操作,可以根据具体场景自由组合使用,方便用户进行数据处理和分析。
4、注意:
参与聚合的字段类型必须是:
- keyword
- 数值
- 日期
- 布尔
三、使用DSL实现聚合
聚合所必须的三要素:
- 聚合名称
- 聚合类型
- 聚合字段
聚合可配置属性:
- size:指定聚合结果数量
- order:指定聚合结果排序方式f
- ield:指定聚合字段
1、桶聚合
GET /hotel/_search
{
"size": 0, // 设置size为0,结果中不包含文档,只包含聚合结果
"aggs": { // 定义聚合
"brandagg": { //给聚合起个名字
"terms": { // 聚合的类型,按照品牌值聚合,所以选择term
"field": "brand", // 参与聚合的字段
"size": 20 // 希望获取的聚合结果数量
}
}
}
}
运行后,数据被按照品牌(brand)划分了
(1)自定义排序规则
(2)限定聚合范围
2、度量聚合
在分类的同时,进行了分数的计算,并且按照平均分做降序
GET /hotel/_search
{
"size": 0,
"aggs": {
"brandagg": {
"terms": {
"field": "brand",
"size": 20,
"order": {
"scoreAgg.avg": "desc"
}
},
"aggs": {
"scoreAgg": {
"stats": {
"field": "score"
}
}
}
}
}
}
四、使用RestAPI实现聚合
1、对品牌进行聚合
@Test
void testAggregation() throws IOException {
// 准备请求对象
SearchRequest request = new SearchRequest();
// 初始化 SearchSourceBuilder
SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
// 设置 size
sourceBuilder.size(0);
// 聚合
sourceBuilder.aggregation(AggregationBuilders
.terms("brandAgg")
.field("brand")
.size(10)
);
// 将 SearchSourceBuilder 设置到 SearchRequest 中
request.source(sourceBuilder);
// 发出请求
SearchResponse response = client.search(request, RequestOptions.DEFAULT);
// 解析结果
Aggregations aggregations = response.getAggregations();
// 根据聚合名称获取聚合结果
Terms brandTerms = aggregations.get("brandAgg");
// 获取桶
List<? extends Terms.Bucket> buckets = brandTerms.getBuckets();
// 遍历
for (Terms.Bucket bucket : buckets) {
String key = bucket.getKeyAsString();
System.out.println(key);
}
}
成功提取出品牌名
2、对品牌、城市、星级进行聚合
1、在service中添加方法
Map<String , List<String>> filters() throws IOException;
2、在实现类中编写聚合方法
@Override
public Map<String, List<String>> filters() throws IOException {
// 准备请求对象
SearchRequest request = new SearchRequest();
// 初始化 SearchSourceBuilder
SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
// 设置 size
sourceBuilder.size(0);
// 聚合
buildAggs(sourceBuilder);
// 将 SearchSourceBuilder 设置到 SearchRequest 中
request.source(sourceBuilder);
// 发出请求
SearchResponse r