如何获取分组结果的最新值?MongoDB聚合查询实现
解决MongoDB按Year分组并计算不同Type最新记录Amount之和的问题
你的需求是过滤StatusCode为"A"的记录,按year分组后,对每个Type的最新记录的Amount求和。原查询里的$reduce逻辑有问题——它只会保留最后一条符合条件的datum条目,没法按Type区分并保留每个类型的最新数据,所以得不到正确结果。
正确的聚合管道查询
db.collection.aggregate([ // 1. 把datum数组拆分成独立文档,方便后续处理每个子记录 { $unwind: "$datum" }, // 2. 过滤出StatusCode为"A"的记录 { $match: { "datum.StatusCode": "A" } }, // 3. 先按年份、类型、日期降序排序,确保每个类型的最新记录排在最前面 { $sort: { "year": 1, "datum.Type": 1, "datum.Date": -1 } }, // 4. 按year+Type分组,直接取每个组的第一条(最新)记录的Amount { $group: { _id: { year: "$year", type: "$datum.Type" }, latestAmount: { $first: "$datum.Amount" } } }, // 5. 按year重新分组,对不同Type的最新Amount求和 { $group: { _id: "$_id.year", Total: { $sum: "$latestAmount" } } }, // 可选:调整输出格式,去掉不必要的_id字段 { $project: { _id: 0, Total: 1 } } ])
针对你的示例文档的执行结果
运行上述查询后,会得到你预期的结果:
{ "Total" : NumberDecimal("720") }
各阶段说明
- $unwind: 将包含datum数组的文档拆分为多个单条文档,每个文档对应原数组中的一个元素,让我们能单独处理每条子记录。
- $match: 精准筛选出
StatusCode为"A"的记录,提前排除不符合条件的数据,减少后续计算量。 - $sort: 按年份、类型分组后,再按日期降序排列,确保每个类型下的最新记录排在分组的第一位。
- 第一个$group: 按
year+Type的组合键分组,用$first直接获取每个组内的第一条(最新)记录的Amount值。 - 第二个$group: 按
year重新聚合,把同一年份下不同类型的最新Amount值求和,得到最终的Total结果。 - $project: 可选阶段,用来优化输出格式,只保留我们需要的Total字段,隐藏自动生成的_id。
如果你需要所有年份的总合(而非按年份分组),只需把第二个$group的_id设为null即可:
{ $group: { _id: null, Total: { $sum: "$latestAmount" } } }
内容的提问来源于stack exchange,提问作者Sudhesh Gnanasekaran
相关产品推荐
相关产品推荐

