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

MongoDB中如何按相同ID且日期差为1天的条件分组数据?

MongoDB实现相同ID下连续日期(差值1天)的分组方案

针对相同ID且日期差值为1天的记录分组需求,普通group by无法直接实现,需要借助MongoDB的聚合管道+窗口函数来完成,具体方案如下:

假设数据结构

假设你的集合名为records,文档结构如下(若Date字段已是MongoDB原生Date类型,可跳过后续的日期转换步骤):

{ "ID": 1, "Date": "3.13.2023", "num": 1 }
{ "ID": 1, "Date": "3.12.2023", "num": 2 }
{ "ID": 1, "Date": "2.14.2023", "num": 3 }

完整聚合管道代码

db.records.aggregate([
  // 1. 将字符串日期转换为MongoDB Date类型(Date字段已是Date类型则跳过)
  {
    $addFields: {
      convertedDate: {
        $dateFromString: {
          dateString: "$Date",
          format: "%m.%d.%Y" // 匹配日期字符串格式:月.日.年
        }
      }
    }
  },
  // 2. 按ID和日期升序排序,确保同ID记录按日期顺序排列
  {
    $sort: {
      ID: 1,
      convertedDate: 1
    }
  },
  // 3. 用窗口函数计算相邻日期差,生成分组标识
  {
    $setWindowFields: {
      partitionBy: "$ID", // 按ID分区处理
      sortBy: { convertedDate: 1 }, // 分区内按日期排序
      output: {
        // 计算当前记录与前一条的日期差(天数)
        prevDateDiff: {
          $dateDiff: {
            startDate: { $lag: "$convertedDate" },
            endDate: "$convertedDate",
            unit: "day"
          }
        },
        // 生成分组ID:非连续日期时累加1,连续日期时累加0
        group_id: {
          $sum: {
            $cond: [
              { $or: [{ $eq: ["$prevDateDiff", null] }, { $ne: ["$prevDateDiff", 1] }] },
              1,
              0
            ]
          },
          window: { documents: ["unbounded", "current"] }
        }
      }
    }
  },
  // 4. 按ID和分组标识聚合记录
  {
    $group: {
      _id: { ID: "$ID", group_id: "$group_id" },
      groupedRecords: { $push: { Date: "$Date", num: "$num" } }
    }
  },
  // 5. 调整输出格式(可选)
  {
    $project: {
      _id: 0,
      ID: "$_id.ID",
      groupedRecords: 1
    }
  }
])

步骤说明

  1. 日期转换:将字符串格式的日期转为MongoDB原生Date类型,确保能使用$dateDiff计算日期差。
  2. 排序:按ID和日期升序排序,保证同ID的记录按时间顺序排列,为后续窗口函数计算相邻日期差做准备。
  3. 窗口函数计算分组标识:
    • $lag获取分区内前一条记录的日期,$dateDiff计算当前日期与前一条的天数差;
    • 通过累加规则生成group_id:第一条记录或日期差不为1天时,group_id累加1,否则累加0,确保连续日期的记录拥有相同group_id。
  4. 分组聚合:按ID和group_id分组,用$push将同组记录聚合为数组。
  5. 格式调整:可选步骤,简化输出结构,让结果更直观。

预期输出

运行上述管道后,会得到符合需求的分组结果:

[
  {
    "ID": 1,
    "groupedRecords": [
      { "Date": "2.14.2023", "num": 3 }
    ]
  },
  {
    "ID": 1,
    "groupedRecords": [
      { "Date": "3.12.2023", "num": 2 },
      { "Date": "3.13.2023", "num": 1 }
    ]
  }
]

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.28 01:45:35