MongoDB对象数组按日期分组统计duration总和的聚合查询问题
问题原因
你的聚合语句存在2处核心错误:
- 变量引用错误:外层
$map迭代的变量名为allDate,你在条件判断中用$allDate.date取值,单$前缀会默认读取文档根级字段,根级不存在allDate字段,所以取值为null。 - 字段名引用错误:内层
$map迭代的$$kv是allDates数组的原生元素,仅包含date和duration两个字段,你写的$$kv.k取值永远为null。
两处错误导致$eq判断永远为真,所有duration都会被累加,最终所有日期对应的总和都是全数组的duration之和。
修正方案
方案1:基于原有写法优化,仅处理单文档内的数组统计
db.collection.aggregate([ { $addFields: { durations: { $arrayToObject: { $map: { input: { $setUnion: "$allDates.date" }, // 先取不重复的日期,避免生成重复key as: "currentDate", in: { k: { $toString: "$$currentDate" }, v: { $sum: { $map: { input: "$allDates", as: "item", in: { $cond: { if: { $eq: [ "$$currentDate", "$$item.date" ] }, then: "$$item.duration", else: 0 } } } } } } } } } } } ])
方案2:支持跨文档全局统计的标准写法
如果你需要对集合中所有文档的allDates统一按日期求和,可以用$unwind+$group的标准聚合流程:
db.collection.aggregate([ // 拆分数组为单独文档 { $unwind: "$allDates" }, // 按日期分组求和 { $group: { _id: "$allDates.date", totalDuration: { $sum: "$allDates.duration" } } }, // 拼装为要求的对象格式 { $group: { _id: null, durations: { $push: { k: { $toString: "$_id" }, v: "$totalDuration" } } } }, { $addFields: { durations: { $arrayToObject: "$durations" } } }, // 可选:移除不需要的_id字段 { $unset: "_id" } ])
内容的提问来源于stack exchange,提问作者panicDisco
相关产品推荐
相关产品推荐

