You need to enable JavaScript to run this app. 如何用MongoDB聚合统计最近7天按星期的购买量并输出指定格式?
优惠活动
大模型
产品
解决方案
定价
更多

如何用MongoDB聚合统计最近7天按星期的购买量并输出指定格式?

实现星期为键的7日购买量统计

现有代码的核心问题

  • 对Date类型字段直接用$substrCP截取字符串,本质是把Date转成UTC时区的ISO字符串后硬截前10位做分组键,既没有处理业务时区的日期偏移问题,也完全没有提取星期维度的信息,最终分组结果按日期字符串聚合,和目标的星期名键的结构完全不匹配。
  • 聚合输出默认是结果数组结构,无法直接生成要求的单对象格式。

调整后的完整聚合实现

按照目标输出格式,需要在原有管道基础上补充日期属性提取、键值映射、结构转换三个核心环节,完整可运行的代码如下:

// 按业务实际时区调整值,东八区对应"Asia/Shanghai"
const TIMEZONE = "Asia/Shanghai";
// 对应$dayOfWeek的返回值做映射:MongoDB中$dayOfWeek返回1=周日、2=周一...7=周六
const WEEK_NAME_LIST = [
  "", // 占位空值,匹配从1开始的返回值下标
  "sunday",
  "monday",
  "tuesday",
  "wednesday",
  "thursday",
  "friday",
  "saturday"
];

Purchase.aggregate([
  // 筛选最近7天的有效购买记录
  {
    $match: {
      date: {
        $gte: new Date(Date.now() - 7 * 24 * 60 * 60 * 1000),
        $lte: new Date()
      }
    }
  },
  // 按星期维度分组统计购买量
  {
    $group: {
      _id: {
        // 提取对应时区下的星期数字,避免UTC时区导致的跨天错配
        weekDayNum: {
          $dayOfWeek: {
            date: "$date",
            timezone: TIMEZONE
          }
        }
      },
      count: { $sum: 1 }
    }
  },
  // 将数字星期值映射为目标格式的键名
  {
    $project: {
      _id: 0,
      k: { $arrayElemAt: [WEEK_NAME_LIST, "$_id.weekDayNum"] },
      v: "$count"
    }
  },
  // 收集所有分组统计结果为数组
  {
    $group: {
      _id: null,
      weekStatList: { $push: "$$ROOT" }
    }
  },
  // 将数组转换为单对象,同时补全无购买记录的星期值为0
  {
    $project: {
      _id: 0,
      statResult: {
        $arrayToObject: {
          $map: {
            input: WEEK_NAME_LIST.slice(1), // 去掉前面的空占位
            as: "weekName",
            in: {
              k: "$$weekName",
              v: {
                $ifNull: [
                  {
                    $first: {
                      $filter: {
                        input: "$weekStatList",
                        as: "item",
                        cond: { $eq: ["$$item.k", "$$weekName"] }
                      }
                    }
                  },
                  0
                ]
              }
            }
          }
        }
      }
    }
  },
  // 将统计结果提升为根文档,得到最终要求的对象结构
  { $replaceRoot: { newRoot: "$statResult" } }
])

注意事项

  • 必须给$dayOfWeek配置业务对应的时区参数,否则会默认按UTC时间计算星期,出现时区偏移导致的统计错配,比如东八区凌晨的订单会被归到前一天的星期维度。
  • 最终输出会自动补全没有购买记录的星期对应值为0,不会出现缺键的情况,完全匹配示例的格式要求。
  • 注意MongoDB的$dayOfWeek返回值规则:1对应周日,2对应周一,依次到7对应周六,不要搞混映射顺序导致键名错位。

内容的提问来源于stack exchange,提问作者Hani Ben Gozi

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.11.01 00:15:04