MongoDB如何按两个字段实现双重分组push数据并添加计算字段
修正后的MongoDB聚合语句
db.collection.aggregate([ // 可选阶段:如果原数据的date字段已经是Date对象,可直接删除此阶段 { "$set": { "date": { "$dateFromString": { "dateString": "$date", "format": "%Y-%m-%d" } } } }, // 第一次分组:按「渠道+年月」维度聚合,计算当前维度的总营收、总销量 { $group: { _id: { channel: "$channel", year: { $year: "$date" }, month: { $month: "$date" } }, tot_revenue: { $sum: "$revenue" }, tot_quantity: { $sum: "$quantity" } } }, // 第二次分组:按「渠道」维度聚合,把同渠道的所有月度数据归集到dates数组 { $group: { _id: "$_id.channel", dates: { $push: { // 拼接为YYYY-MM格式的月份字符串,自动给个位数月份补前导零 date: { $concat: [ { $toString: "$_id.year" }, "-", { $cond: [ { $lt: [ "$_id.month", 10 ] }, { $concat: [ "0", { $toString: "$_id.month" } ] }, { $toString: "$_id.month" } ] } ] }, totals: { tot_revenue: "$tot_revenue", tot_quantity: "$tot_quantity", // 计算单量平均营收,加$ifNull避免总销量为0时出现计算错误 avg_revenue: { $ifNull: [ { $divide: [ "$tot_revenue", "$tot_quantity" ] }, 0 ] } } } } } }, // 调整输出字段格式,和你要求的返回结构对齐 { $project: { _id: 0, channel: "$_id", dates: 1 } } ])
原写法的问题说明
- 分组逻辑颠倒:第一次按「渠道+年月」聚合后,第二次应该按渠道维度归集所有月度数据,而非再次按年月分组
- 缺少聚合计算:原逻辑只做了原始数据推送,没有对营收、销量做求和计算
- 缺失格式处理:没有做月份字符串格式化、平均营收计算的逻辑
- 输出结构未对齐:没有调整最终输出的字段命名和结构
内容的提问来源于stack exchange,提问作者khateeb
相关产品推荐
相关产品推荐

