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

MongoDB预订记录按年/月/周/日分层结构化实现咨询

实现MongoDB预订记录的年→月→周→日多层嵌套分组

嘿,这个需求我之前帮不少开发者处理过,用MongoDB的**聚合管道(Aggregation Pipeline)**就能完美实现你想要的多层嵌套结构,我给你拆解下具体思路和实现步骤:

核心思路:逐层聚合+嵌套分组

我们可以通过聚合管道的多阶段$group操作,从最顶层的年份开始,逐层向下嵌套月份、周、日的分组,同时把对应层级的预订记录嵌入到对应节点里。

步骤1:提取时间维度字段

首先需要从你的预订日期字段(假设是bookingDate)中提取出年、月、周、日这几个维度的信息,用MongoDB的日期操作符就能轻松实现:

  • $year: 提取日期的年份
  • $month: 提取月份(1-12)
  • $week: 提取ISO周数(0-53,注意MongoDB的周默认遵循ISO标准,以周一为一周第一天)
  • $dayOfMonth: 提取当月的日期

我们可以用$project阶段来生成这些字段:

{
  $project: {
    bookingDate: 1,
    // 保留其他你需要的预订字段,比如customerName、roomId等
    customerName: 1,
    roomId: 1,
    year: { $year: "$bookingDate" },
    month: { $month: "$bookingDate" },
    week: { $week: "$bookingDate" },
    day: { $dayOfMonth: "$bookingDate" }
  }
}

步骤2:逐层嵌套分组

接下来是关键的多层分组,我们从最底层的「日」开始往上聚合,最终嵌套成年→月→周→日的结构:

具体的聚合代码示例(假设集合名为bookings):

db.bookings.aggregate([
  // 步骤1:提取时间维度字段
  {
    $project: {
      bookingDate: 1,
      customerName: 1,
      roomId: 1,
      year: { $year: "$bookingDate" },
      month: { $month: "$bookingDate" },
      week: { $week: "$bookingDate" },
      day: { $dayOfMonth: "$bookingDate" }
    }
  },
  // 按日分组,收集当日的预订记录
  {
    $group: {
      _id: {
        year: "$year",
        month: "$month",
        week: "$week",
        day: "$day"
      },
      dayBookings: { $push: "$$ROOT" } // 把当日所有记录存到dayBookings数组
    }
  },
  // 按周分组,嵌套日的分组结果
  {
    $group: {
      _id: {
        year: "$_id.year",
        month: "$_id.month",
        week: "$_id.week"
      },
      weekDays: { $push: { day: "$_id.day", bookings: "$dayBookings" } }
    }
  },
  // 按月分组,嵌套周的分组结果
  {
    $group: {
      _id: {
        year: "$_id.year",
        month: "$_id.month"
      },
      monthWeeks: { $push: { week: "$_id.week", days: "$weekDays" } }
    }
  },
  // 按年分组,嵌套月的分组结果
  {
    $group: {
      _id: "$_id.year",
      yearMonths: { $push: { month: "$_id.month", weeks: "$monthWeeks" } }
    }
  },
  // 可选:给年、月、周排序,让结构更规整
  {
    $sort: { _id: 1 }
  },
  // 可选:替换默认_id字段为更友好的year字段
  {
    $addFields: {
      year: "$_id",
      _id: "$$REMOVE"
    }
  }
])

步骤3:优化与注意事项

  • 索引优化:如果bookingDate字段有索引,聚合时会大幅提升性能,尤其是数据量较大时
  • 数据过滤:如果不需要全量数据,可以先加一个$match阶段过滤时间范围(比如{ $match: { bookingDate: { $gte: ISODate("2023-01-01") } } }),减少后续处理的数据量
  • 周数自定义:如果你需要按自然周(比如周日为第一天),可以用$dayOfWeek配合计算调整周数的逻辑
  • 字段裁剪:在$project阶段只保留你需要的字段,避免传递不必要的数据,提升效率

最终你得到的结果结构大概是这样的:

[
  {
    "year": 2024,
    "yearMonths": [
      {
        "month": 5,
        "weeks": [
          {
            "week": 19,
            "days": [
              {
                "day": 13,
                "bookings": [
                  { /* 当日的预订记录详情 */ }
                ]
              }
            ]
          }
        ]
      }
    ]
  }
]

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.19 03:37:34