mongoTemplate 使用管道聚合实现 根据某个条件去重

在日常业务中可能会遇到根据数据库某个字段进行去重,我们可以使用mongotemplate.findDistinct方法。但是使用这个方法不太好匹配其他例如 排序、分页、获取总数等业务。为了能更好的实现业务我们可以使用mongo 的 管道聚合来实现。下面直接展示代码:

条件+去重+排序+分页

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
public void group() {
int page = 1; //页码
int size = 4; //页长

Criteria criteria = Criteria.where("num").lte(10);
Aggregation aggregation = Aggregation.newAggregation(
Aggregation.match(criteria), //过滤条件
Aggregation.group("age") // 根据指定字段去重
.first("$$ROOT").as("document"), // 保留整个文档
Aggregation.replaceRoot("document"), // 将保存的整个文档对象作为输出文档
Aggregation.sort(Sort.by(Sort.Direction.ASC, "num")), // 根据指定字段排序
Aggregation.skip((page - 1) * size), // 跳过指定的页数
Aggregation.limit(size)
);
AggregationResults<User> results = mongoTemplate.aggregate(aggregation, "user", User.class);
List<User> userList = results.getMappedResults();
Aggregation countAgg = Aggregation.newAggregation(
Aggregation.match(criteria), // 过滤条件
Aggregation.group("age"), // 根据指定字段去重
Aggregation.count().as("total") // 计算去重后的总数
);

AggregationResults<org.bson.Document> countResults = mongoTemplate.aggregate(countAgg, "user", org.bson.Document.class);
int total = 0;
if (!countResults.getMappedResults().isEmpty()) {
total = countResults.getMappedResults().get(0).getInteger("total");
}

System.out.println("查询出来的数据");
System.out.println("当前为第" + page + "页");
userList.forEach(System.out::println);
System.out.println("总数为:" + total);
}

实体类

1
2
3
4
5
public class User {
private Integer num;
private String name;
private Integer age;
}

数据库数据

执行结果


mongoTemplate 使用管道聚合实现 根据某个条件去重
https://blog.wilsonj.ltd/2024/10/15/blog004-1/
作者
WilsonJ
发布于
2024年10月15日
许可协议