You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在MongoDB中按渠道分组统计当年与上一年的营收、销量对应数值

MongoDB 按渠道统计当年及上一年营收销量聚合方案

前提说明:以下示例以统计2021年作为当前年为例,和你给出的预期输出逻辑匹配,如果需要调整统计年份,修改对应过滤条件和取值判断即可。


完整聚合查询语句

db.collection.aggregate([
  // 1. 提取日期年份,补全缺失的quantity字段默认值为0
  {
    $addFields: {
      year: { $toInt: { $substrCP: ["$date", 0, 4] } },
      quantity: { $ifNull: ["$quantity", 0] }
    }
  },
  // 2. 过滤只保留当前年、上一年数据,减少无效计算
  {
    $match: {
      year: { $in: [2020, 2021] }
    }
  },
  // 3. 按渠道+年份分组,统计单年单渠道的总营收、总销量
  {
    $group: {
      _id: {
        channel: "$channel",
        year: "$year"
      },
      total_revenue: { $sum: "$revenue" },
      total_quantity: { $sum: "$quantity" }
    }
  },
  // 4. 按渠道二次分组,把同渠道两年的统计结果聚合到同一文档
  {
    $group: {
      _id: "$_id.channel",
      year_stats: {
        $push: {
          k: { $toString: "$_id.year" },
          v: {
            revenue: "$total_revenue",
            quantity: "$total_quantity"
          }
        }
      }
    }
  },
  // 5. 把年份统计数组转成键值对对象,方便后续取值
  {
    $replaceRoot: {
      newRoot: {
        $mergeObjects: [
          { channel: "$_id" },
          { $arrayToObject: "$year_stats" }
        ]
      }
    }
  },
  // 6. 映射为目标输出格式,缺失年份数据默认补0
  {
    $project: {
      _id: 0,
      channel: 1,
      current_year_revenue: { $ifNull: ["$2021.revenue", 0] },
      prev_year_revenue: { $ifNull: ["$2020.revenue", 0] },
      current_year_quantity: { $ifNull: ["$2021.quantity", 0] },
      prev_year_quantity: { $ifNull: ["$2020.quantity", 0] }
    }
  }
])

兼容说明

如果你的date字段存储的是MongoDB原生ISODate类型而非字符串,把第一步提取year的逻辑替换为year: { $year: "$date" }即可。
如果需要动态统计任意年份的同比数据,聚合前传入参数替换2021、2020的硬编码值即可。


内容的提问来源于stack exchange,提问作者khateeb

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.02 02:45:01