MongoDB分组聚合中获取用户当日出入门信息的方法
MongoDB聚合查询获取考勤入门/出门门禁信息
你的问题核心是在$group阶段无法直接引用同阶段计算的entry_time和exit_time来关联对应门禁,因为聚合阶段的字段是并行计算的,无法互相引用。可以通过分阶段处理解决:
完整聚合管道示例
db.collection.aggregate([ // 第一步:按用户+日期分组,收集当日所有门禁记录、最早/最晚时间 { $group: { _id: { user_uuid: "$actor.user.uuid", date_string: { $dateToString: { format: "%Y-%m-%d", date: { $toDate: "$time" }, timezone: "America/New_York" } } }, entry_time: { $min: "$time" }, exit_time: { $max: "$time" }, user_name: { $first: "$actor.user.name" }, // 同用户同日期字段不变,直接取第一条 email: { $first: "$actor.user.email" }, door_records: { $push: { time: "$time", door_name: "$door.name" } } } }, // 第二步:从门禁记录中匹配对应最早/最晚时间的门禁 { $addFields: { entry_door: { $arrayElemAt: [ { $map: { input: { $filter: { input: "$door_records", cond: { $eq: ["$$this.time", "$entry_time"] } } }, as: "record", in: "$$record.door_name" } }, 0 // 取第一个匹配的门禁(多记录同时间时可按需调整) ] }, exit_door: { $arrayElemAt: [ { $map: { input: { $filter: { input: "$door_records", cond: { $eq: ["$$this.time", "$exit_time"] } } }, as: "record", in: "$$record.door_name" } }, 0 ] } } }, // 可选:移除冗余的原始记录数组,精简结果 { $project: { door_records: 0 } } ])
关键逻辑说明
$group阶段优化:
- 用
$push收集当日所有time和door_name到数组,保留后续匹配的原始数据 - 用
$first提取用户固定信息,避免重复存储
- 用
$addFields阶段匹配门禁:
$filter筛选出与entry_time/exit_time匹配的记录$map提取筛选结果中的门禁名称$arrayElemAt取第一条匹配结果(若存在多条同时间记录,可根据业务需求调整为保留全部)
内容的提问来源于stack exchange,提问作者vish anand
相关产品推荐
相关产品推荐

