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

如何使用MongoDB Aggregate创建活跃客户时间序列?

MongoDB聚合实现跨期活跃客户的月度时间序列统计

要解决单个客户在多个月份被统计的问题,核心思路是把每个客户的活跃期拆分成对应每个月份的独立记录,再按年月分组统计。以下是完整可运行的聚合管道:

完整聚合代码

db.customers.aggregate([
  // 1. 统一处理活跃结束日期:未结束的客户用当前日期替代
  {
    $addFields: {
      effectiveEndDate: { $ifNull: ["$activeEndDate", new Date()] }
    }
  },
  // 2. 提取活跃起始/结束的年月对象,计算活跃总月数
  {
    $addFields: {
      startYM: {
        year: { $year: "$activeStartDate" },
        month: { $month: "$activeStartDate" }
      },
      endYM: {
        year: { $year: "$effectiveEndDate" },
        month: { $month: "$effectiveEndDate" }
      },
      totalActiveMonths: {
        $add: [
          { $multiply: [{ $subtract: ["$endYM.year", "$startYM.year"] }, 12] },
          { $subtract: ["$endYM.month", "$startYM.month"] },
          1 // 包含起始月份本身
        ]
      }
    }
  },
  // 3. 生成月份偏移量数组,再展开成单条记录
  {
    $addFields: {
      monthOffsets: { $range: [0, "$totalActiveMonths", 1] }
    }
  },
  { $unwind: "$monthOffsets" },
  // 4. 根据偏移量计算每个对应的年月
  {
    $addFields: {
      currentYM: {
        $let: {
          vars: {
            // 把月份转成0基计算(1月→0),加上偏移量后再转回1基
            totalMonths: { $add: ["$startYM.month", "$monthOffsets", -1] },
            yearShift: { $floor: { $divide: ["$$totalMonths", 12] } },
            targetMonth: { $add: [{ $mod: ["$$totalMonths", 12] }, 1] }
          },
          in: {
            year: { $add: ["$startYM.year", "$$yearShift"] },
            month: "$$targetMonth"
          }
        }
      }
    }
  },
  // 5. 按年月分组统计活跃客户数
  {
    $group: {
      _id: "$currentYM",
      activeCustomers: { $sum: 1 }
    }
  },
  // 6. 按时间顺序排序
  {
    $sort: { "_id.year": 1, "_id.month": 1 }
  }
])

核心逻辑拆解

  • 统一活跃结束时间:用$ifNull将未终止活跃(activeEndDate为null)的客户,结束时间设为当前日期,确保这类客户能被统计到最新月份。
  • 拆分活跃期为单月记录:通过计算活跃总月数生成偏移量数组,再用$unwind展开,让每个客户的每一个活跃月份都对应一条独立文档——这是实现“单个客户多分组统计”的关键。
  • 计算对应年月:基于起始年月和偏移量,通过数学运算处理跨年跨月的边界情况,确保每个偏移量都能得到正确的年月值。
  • 分组排序:按计算出的年月分组统计数量,最后排序得到有序的时间序列。

输出效果

最终会生成你需要的格式:

[
  { "_id": { "year": 2022, "month": 7 }, "activeCustomers": 500 },
  { "_id": { "year": 2022, "month": 8 }, "activeCustomers": 520 },
  // ... 后续月份数据
]

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.17 00:51:20