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

如何通过Spring Data MongoDB聚合查询获取各projectId的统计数据

解决方案:获取MongoDB聚合查询中每个projectId的统计值

1. 定义聚合结果映射类

Spring Data MongoDB需要将聚合结果映射到Java对象,创建一个DTO类来接收分组后的统计数据,注意projectId为long类型,totalAmount对应MongoDB的decimal类型,用Java的BigDecimal接收:

import java.math.BigDecimal;

public class ProjectStats {
    private long projectId;
    private long totalCount;
    private BigDecimal totalAmount;

    // 必须提供全参构造方法,Spring Data MongoDB会用它映射结果
    public ProjectStats(long projectId, long totalCount, BigDecimal totalAmount) {
        this.projectId = projectId;
        this.totalCount = totalCount;
        this.totalAmount = totalAmount;
    }

    // Getter方法
    public long getProjectId() { return projectId; }
    public long getTotalCount() { return totalCount; }
    public BigDecimal getTotalAmount() { return totalAmount; }
}

2. 执行聚合查询并映射结果

通过MongoTemplate执行你定义的聚合操作,指定结果类型为上面的ProjectStats:

// 假设已注入MongoTemplate
@Autowired
private MongoTemplate mongoTemplate;

// 补全原代码中updatedTime的gt/lt参数(示例传入起止时间)
Aggregation aggregate = newAggregation(
        match(Criteria.where("projectId").in(projectIdList)
                .and("isAvailable").is(false) // 单个值匹配用is比in更高效
                .and("status").is("rejected")
                .and("updatedTime").gt(startTime).lt(endTime)),
        group("projectId")
                .count().as("totalCount")
                .sum(ConvertOperators.Convert.convertValueOf("amount").to("decimal")).as("totalAmount")
);

// 执行聚合并映射结果
AggregationResults<ProjectStats> results = mongoTemplate.aggregate(aggregate, "你的集合名称", ProjectStats.class);
List<ProjectStats> projectStatsList = results.getMappedResults();

3. 快速获取单个projectId的统计值

如果需要通过projectId快速查找对应数据,可将结果列表转为Map<Long, ProjectStats>:

import java.util.stream.Collectors;

Map<Long, ProjectStats> statsMap = projectStatsList.stream()
        .collect(Collectors.toMap(ProjectStats::getProjectId, stats -> stats));

// 示例:获取指定projectId的统计数据
long targetProjectId = 123L;
if (statsMap.containsKey(targetProjectId)) {
    ProjectStats stats = statsMap.get(targetProjectId);
    System.out.println("统计数量:" + stats.getTotalCount());
    System.out.println("统计金额:" + stats.getTotalAmount());
}

注意事项

  • 原代码中isAvailable.in(false)建议改为isAvailable.is(false),单个值匹配无需用in语法
  • 确保updatedTime的gt/lt参数已正确传入,否则match条件会失效
  • 如果集合名称通过实体类@Document注解指定,可直接传入实体类class替代字符串集合名,比如YourEntity.class

内容的提问来源于stack exchange,提问作者trytocode

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.08 05:10:30