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

如何在MongoDB中按周六至周五的非标准周进行聚合统计?

按周六到周五的非标准周统计员工总工时

嘿,这个需求我之前碰到过!MongoDB默认的周起始是周日或周一(取决于版本和配置),要实现周六开始、周五结束的周统计,核心就是手动调整日期的分组依据,把同一周的所有日期映射到同一个起始点(也就是当周的周六),然后再分组求和就行。

完整聚合查询代码

db.myCollection.aggregate([
  // 第一步:过滤目标员工,可按需添加日期范围过滤
  { $match: { Employee: "Bill" } },
  // 第二步:计算每条记录所属的「周六起始周」的周六日期
  {
    $addFields: {
      weekStart: {
        $dateSubtract: {
          startDate: "$Date",
          unit: "day",
          amount: {
            $cond: {
              if: { $eq: [ { $dayOfWeek: "$Date" }, 7 ] }, // MongoDB中$dayOfWeek返回7代表周六
              then: 0, // 当天就是周六,无需偏移
              else: { $subtract: [ { $dayOfWeek: "$Date" }, 1 ] } // 周日减1天、周一减2天...直到周五减6天,回到上一个周六
            }
          }
        }
      }
    }
  },
  // 第三步:按员工+周起始日期分组,统计总工时
  {
    $group: {
      _id: {
        Employee: "$Employee",
        weekStart: "$weekStart"
      },
      totalHours: { $sum: "$Hours" }
    }
  },
  // 可选:按周起始日期排序,让结果更直观
  { $sort: { "_id.weekStart": 1 } }
])

关键步骤解释

  • $match阶段:和你熟悉的标准写法一样,先过滤出目标员工的记录,也可以在这里加上Date的范围条件,减少后续计算的数据量。
  • $addFields阶段:这是实现非标准周的核心。MongoDB的$dayOfWeek函数会返回1(周日)到7(周六)的数值,我们通过条件判断:
    • 如果当前日期是周六,直接保留当天作为周起始点;
    • 如果是周日到周五,减去对应的天数(周日减1天、周一减2天...),把日期偏移到上一个周六,这样同一周(周六到周五)的所有日期都会映射到同一个周六。
  • $group阶段:按员工和周起始日期分组,用$sum累加该周的工时总数。
  • $sort阶段:可选步骤,让结果按周的时间顺序排列,方便查看。

扩展:显示周结束日期(周五)

如果需要在结果中明确显示周的结束日期(周五),可以在$addFields阶段添加一个weekEnd字段:

$addFields: {
  weekStart: { /* 上面的代码 */ },
  weekEnd: { $dateAdd: { startDate: "$weekStart", unit: "day", amount: 6 } }
}

这样分组后的结果里就能看到完整的「周六-周五」区间了。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.25 03:42:57