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

如何高效生成带可用性状态的月度日期数组?

最优实现方案:用MongoDB聚合管道完成全流程计算

直接把生成日期、匹配可用性的逻辑都放到MongoDB端处理,彻底避免客户端拉取数据后逐天校验的低效操作,以下是直观高效的聚合管道实现:

假设要生成2023年7月的日期数组,核心思路是:先在数据库中生成当月所有日期的基础序列,再将每个日期与availabilities集合中的时间段记录做关联,自动标记状态。

完整聚合管道代码

db.aggregate([
  // 1. 生成目标月份的第一天和最后一天
  {
    $addFields: {
      firstDayOfMonth: ISODate("2023-07-01T00:00:00Z"),
      lastDayOfMonth: ISODate("2023-07-31T23:59:59Z")
    }
  },
  // 2. 计算当月总天数,生成日期偏移量序列
  {
    $addFields: {
      totalDays: {
        $add: [
          { $dateDiff: { startDate: "$firstDayOfMonth", endDate: "$lastDayOfMonth", unit: "day" } },
          1
        ]
      },
      dayOffsets: { $range: [0, "$totalDays"] }
    }
  },
  // 3. 展开偏移量,生成每个日期的字符串格式
  { $unwind: "$dayOffsets" },
  {
    $addFields: {
      date: {
        $dateToString: {
          format: "%Y-%m-%d",
          date: {
            $dateAdd: {
              startDate: "$firstDayOfMonth",
              amount: "$dayOffsets",
              unit: "day"
            }
          }
        }
      }
    }
  },
  // 4. 仅保留日期字段,作为基础序列
  { $project: { _id: 0, date: 1 } },
  // 5. 关联availabilities集合,匹配覆盖当前日期的记录
  {
    $lookup: {
      from: "availabilities",
      let: { currentDateStr: "$date" },
      pipeline: [
        {
          $match: {
            $expr: {
              $and: [
                // 可用性记录的开始时间不晚于当前日期的结束时间
                { $lte: ["$startDateTime", { $dateFromString: { dateString: { $concat: ["$$currentDateStr", "T23:59:59Z"] } } }] },
                // 可用性记录的结束时间不早于当前日期的开始时间
                { $gte: ["$endDateTime", { $dateFromString: { dateString: { $concat: ["$$currentDateStr", "T00:00:00Z"] } } }] }
              ]
            }
          }
        },
        { $project: { _id: 0, availabilityType: 1 } },
        { $limit: 1 } // 若同一天有多个记录,取第一个;可根据需求调整优先级逻辑
      ],
      as: "matchedAvailability"
    }
  },
  // 6. 标记状态:有匹配记录则用对应类型,否则为available
  {
    $addFields: {
      availabilityType: {
        $ifNull: [
          { $arrayElemAt: ["$matchedAvailability.availabilityType", 0] },
          "available"
        ]
      }
    }
  },
  // 7. 整理格式并按日期排序
  { $project: { date: 1, availabilityType: 1 } },
  { $sort: { date: 1 } },
  // 8. 可选:将结果合并为一个数组返回
  {
    $group: {
      _id: null,
      monthlyAvailability: { $push: "$$ROOT" }
    }
  },
  { $project: { _id: 0, monthlyAvailability: 1 } }
])

核心优势

  • 性能碾压客户端方案:所有计算在数据库端完成,无需拉取全量availabilities数据到本地循环校验,大幅减少网络传输和CPU消耗
  • 边界处理准确:用MongoDB原生日期函数处理时间范围匹配,避免客户端手动计算日期的漏判、错判问题
  • 灵活可扩展:如果后续需要处理同一天多记录的优先级、跨月可用性等场景,只需修改$lookup内的匹配逻辑或添加分组规则即可

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.16 03:09:53