如何用Spring Data MongoDB实现TopN分组聚合?
用Spring Data MongoDB实现带$topN的分组聚合
实现思路
对应你给出的MongoDB原生聚合管道,我们可以通过Spring Data MongoDB的Aggregation API分两步构建:先创建$match过滤阶段,再构建包含$topN累加器的$group分组阶段,最后通过MongoTemplate执行聚合操作。
具体代码实现
1. 构建匹配阶段($match)
使用MatchOperation实现文档过滤,对应原生管道的$match部分:
import org.springframework.data.mongodb.core.aggregation.Aggregation; import org.springframework.data.mongodb.core.aggregation.MatchOperation; import org.springframework.data.mongodb.core.query.Criteria; import java.time.Instant; import java.util.Date; // 构建匹配条件 MatchOperation matchOperation = Aggregation.match( Criteria.where("field000").regex(".*MATCHTHIS.*") .and("created").lte(Date.from(Instant.parse("2030-05-25T00:00:00.000Z"))) );
2. 构建分组阶段($group)
由于部分Spring Data MongoDB版本未直接封装$topN的快捷方法,我们可以通过自定义AggregationExpression来实现原生管道中$topN的逻辑:
import org.springframework.data.mongodb.core.aggregation.GroupOperation; import org.springframework.data.mongodb.core.aggregation.AggregationExpression; import org.bson.Document; import java.util.Arrays; // 构建分组及$topN逻辑 GroupOperation groupOperation = Aggregation.group("field001") .addField("field001s") .withValue(AggregationExpression.from(context -> new Document("$topN", new Document() .append("output", Arrays.asList("$field002", "$created")) .append("sortBy", new Document("created", -1)) .append("n", 1) ) ));
3. 组合聚合管道并执行
将两个阶段组合成完整的聚合管道,通过MongoTemplate执行并接收结果:
import org.springframework.data.mongodb.core.MongoTemplate; import org.springframework.data.mongodb.core.aggregation.AggregationResults; // 组合聚合管道 Aggregation aggregation = Aggregation.newAggregation(matchOperation, groupOperation); // 执行聚合,替换为你的集合名和结果实体类 AggregationResults<GroupTopNResult> results = mongoTemplate.aggregate( aggregation, "your-collection-name", GroupTopNResult.class ); // 获取结果列表 List<GroupTopNResult> resultList = results.getMappedResults();
4. 定义结果实体类
根据$topN的输出结构,定义对应的结果实体类:
import java.util.Date; import java.util.List; public class GroupTopNResult { // 对应分组的_id(即field001的值) private String _id; // $topN返回的是数组,即使n=1也会返回长度为1的数组 private List<TopNItem> field001s; // 内部类对应$topN的output字段 public static class TopNItem { private String field002; private Date created; // getter和setter方法 public String getField002() { return field002; } public void setField002(String field002) { this.field002 = field002; } public Date getCreated() { return created; } public void setCreated(Date created) { this.created = created; } } // getter和setter方法 public String get_id() { return _id; } public void set_id(String _id) { this._id = _id; } public List<TopNItem> getField001s() { return field001s; } public void setField001s(List<TopNItem> field001s) { this.field001s = field001s; } }
版本注意事项
$topN是MongoDB 5.0及以上版本支持的聚合操作符,确保你的MongoDB服务版本符合要求。- Spring Data MongoDB版本建议使用3.3及以上,以更好地兼容MongoDB 5.0+的新特性。
内容的提问来源于stack exchange,提问作者Rafael
相关产品推荐
相关产品推荐

