基于Ignition字段值分组MongoDB大数据集的实现方案
MongoDB 按连续
ignition=1分组实现方案 需要对MongoDB中的86400条记录进行分组:将**连续出现ignition=1**的记录归为同一组,直到遇到ignition=0时结束当前组,后续的ignition=1记录开启新组,以此循环。
示例输入数据:
[ { ignition: 1, time: 112 }, { ignition: 1, time: 193 }, { ignition: 0, time: 115 }, { ignition: 1, time: 116 }, { ignition: 1, time: 117 }, { ignition: 1, time: 118 }, { ignition: 0, time: 119 }, { ignition: 1, time: 120 }, { ignition: 1, time: 121 }, { ignition: 1, time: 122 }, { ignition: 0, time: 123 }, ]
期望输出结果(注:原输出的重复key格式不合法,调整为合法数组格式):
[ { time: [112, 193] }, { time: [116, 117, 118] }, { time: [120, 121, 122] } ]
实现步骤(MongoDB聚合管道)
通过MongoDB聚合框架的$setWindowFields、$group等操作,可实现连续分组逻辑:
完整聚合查询代码
db.collection.aggregate([ // 1. 按时间排序,保证时序正确(若记录本身按时序存储,可替换为_id或其他时序字段) { $sort: { time: 1 } }, // 2. 生成分组标识:每开启一段连续ignition=1的序列,groupId递增 { $setWindowFields: { partitionBy: null, sortBy: { time: 1 }, output: { groupId: { $sum: { $cond: [ { $or: [ // 上一条是ignition=0,当前是ignition=1,开启新组 { $and: [{ $eq: ["$ignition", 1] }, { $eq: ["$$prev.ignition", 0] }] }, // 第一条记录且ignition=1,直接生成第一个组 { $and: [{ $eq: ["$ignition", 1] }, { $eq: ["$$prev", null] }] } ] }, 1, 0 ] }, window: { documents: ["unbounded", "current"] } } } } }, // 3. 过滤掉ignition=0的无效记录 { $match: { ignition: 1 } }, // 4. 按groupId分组,收集对应time值 { $group: { _id: "$groupId", time: { $push: "$time" } } }, // 5. 整理输出格式,去掉冗余的_id字段 { $project: { _id: 0, time: 1 } } ])
关键逻辑说明
- 排序是核心前提:必须保证记录按时间顺序处理,否则连续分组的判断会完全错误;
groupId的生成逻辑:通过窗口函数累加,每触发一次"从0切换到1"的条件,就生成新的分组ID,保证同一段连续ignition=1的记录拥有相同ID;- 最终过滤掉
ignition=0的记录,只保留有效分组的时间数据。
内容的提问来源于stack exchange,提问作者Muhammad Nabeel
相关产品推荐
相关产品推荐

