Spring Data MongoDB按日期范围分组统计总计数和条件计数报错问题
Spring Data MongoDB 按天分组双指标统计实现方案
核心逻辑说明
无需拆分两个GroupOperation,直接在同一个分组阶段同时计算总量和条件求和即可。拆分两次分组会导致第一次聚合后的结果结构无法匹配第二次分组的字段要求,是你报错的核心原因。
完整代码实现
首先导入需要的工具类:
import org.springframework.data.mongodb.core.aggregation.Aggregation; import org.springframework.data.mongodb.core.aggregation.ConditionalOperators; import org.springframework.data.mongodb.core.aggregation.DateOperators; import org.springframework.data.mongodb.core.query.Criteria;
编写聚合逻辑:
// 1. 构造日期范围过滤规则,可替换为你自己的时间字段、起止时间参数 Criteria dateCriteria = Criteria.where("createTime").gte(startTime).lt(endTime); Aggregation aggregation = Aggregation.newAggregation( // 过滤阶段:仅保留符合日期范围的OTP数据 Aggregation.match(dateCriteria), // 投影阶段:生成格式化的天维度日期字段,格式可按需调整 Aggregation.project("status") .and(DateOperators.DateToString.dateOf("createTime").toString("%Y-%m-%d")).as("otpDate"), // 核心单分组阶段:同时统计两个指标 Aggregation.group("otpDate") // 统计每日总OTP数量 .count().as("totalOtpCount") // 条件统计验证成功数量:状态匹配时计数+1,否则+0 .sum(ConditionalOperators.when(Criteria.where("status").is("VERIFIED")).then(1).otherwise(0)).as("verifiedCount") ); // 执行聚合,OtpStat为自定义结果接收实体,替换为你自己的集合名 AggregationResults<OtpStat> results = mongoTemplate.aggregate(aggregation, "你的OTP集合名", OtpStat.class); List<OtpStat> statList = results.getMappedResults();
结果接收实体示例
public class OtpStat { private String otpDate; private Long totalOtpCount; private Long verifiedCount; // 省略getter、setter、构造方法 }
对应原生MongoDB聚合逻辑
和上述Spring Data代码完全对齐的原生聚合语句如下:
[ { $match: { "createTime": { "$gte": ISODate("你的起始时间"), "$lt": ISODate("你的结束时间") } } }, { $project: { "status": 1, "otpDate": { $dateToString: { format: "%Y-%m-%d", date: "$createTime" } } } }, { $group: { "_id": "$otpDate", "totalOtpCount": { "$sum": 1 }, "verifiedCount": { "$sum": { $cond: [{ $eq: ["$status", "VERIFIED"] }, 1, 0] } } } } ]
内容的提问来源于stack exchange,提问作者Geeganage Punsara Prathibha
相关产品推荐
相关产品推荐

