MongoDB多条件分组求和:按Partner_ID、Scheme_Name及月份统计Net_Amount
MongoDB聚合查询:按Scheme_Name和月份分组统计Net_Amount总和
文档结构
{ "_id" : ObjectId("63ceb466db8c0f5500ea0aaa"), "Partner_ID" : "662347848", "EarningsData" : [ { "From_Date" : ISODate("2022-01-10T18:30:00.000Z"), "Scheme_Name" : "CUSTOMERWINBACKJCA01", "Net_Amount" : 256 }, { "From_Date" : ISODate("2022-02-10T18:30:00.000Z"), "Scheme_Name" : "CUSTOMERWINBACKJCA01", "Net_Amount" : 285 } ], "createdAt" : ISODate("2023-01-23T16:23:02.440Z") }
需求
针对指定Partner_ID,按Scheme_Name和From_Date的月份分组,统计Net_Amount的总和,预期输出:
[ { "Month" : 1, "Scheme_Name" : "CUSTOMERWINBACKJCA01", "Net_Amount": 256 }, { "Month" : 2, "Scheme_Name" : "CUSTOMERWINBACKJCA01", "Net_Amount": 285 } ]
现有查询问题
已实现按Scheme_Name分组求和,但无法整合按From_Date月份统计的逻辑,现有代码:
var projectQry = [ { "$unwind": { path : '$EarningsData', preserveNullAndEmptyArrays: true } }, { $match: { "Partner_ID": userId } }, { $group : { _id: "$EarningsData.Scheme_Name", Net_Amount: { $sum: "$EarningsData.Net_Amount" } } }, { $project: { _id: 0, Scheme_Name: "$_id", Net_Amount: 1 } } ];
修改后的聚合管道
var projectQry = [ // 先过滤指定Partner_ID,减少后续处理数据量 { $match: { "Partner_ID": userId } }, // 展开EarningsData数组 { "$unwind": { path: '$EarningsData', preserveNullAndEmptyArrays: true } }, // 提取From_Date的月份,存入临时字段 { $addFields: { "EarningsData.Month": { $month: "$EarningsData.From_Date" } } }, // 按Scheme_Name和月份联合分组,统计Net_Amount总和 { $group: { _id: { Scheme_Name: "$EarningsData.Scheme_Name", Month: "$EarningsData.Month" }, Net_Amount: { $sum: "$EarningsData.Net_Amount" } } }, // 调整输出格式,匹配预期结构 { $project: { _id: 0, Scheme_Name: "$_id.Scheme_Name", Month: "$_id.Month", Net_Amount: 1 } } ];
关键修改说明
- 优化$match顺序:先过滤目标
Partner_ID的文档,再执行数组展开,减少后续阶段需要处理的数据量,提升查询性能。 - 新增$addFields阶段:使用MongoDB的
$month操作符从From_Date中提取月份数值,作为分组依据。 - 修改分组键:将
Scheme_Name和提取的Month作为联合_id,确保同一方案下同一月份的数据被聚合在一起。 - 调整输出映射:从联合分组键中拆分出
Scheme_Name和Month字段,输出结构完全匹配预期结果。
内容的提问来源于stack exchange,提问作者user20933891
相关产品推荐
相关产品推荐

