You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.20 21:45:45