MongoDB聚合查询如何筛选timeClock中符合指定日期的特定值?
问题根源
你现有聚合逻辑的核心问题是筛选时机和方式错误:
- 你注释的$match阶段放在了$group之后,此时
timeClock已经是嵌套对象的数组,直接对数组字段做精确匹配无法命中单条记录 - 你写的日期筛选代码里把
moment.utc(date).toDate()用引号包裹当成了字符串,而非实际的Date类型值,导致匹配失效 - 你在$group阶段用
$push把所有记录塞回数组,自然会保留全部打卡记录
修正方案
调整筛选顺序,在$unwind拆分打卡记录之后、分组之前做日期过滤,分组时直接取单条符合条件的记录即可:
// 先计算目标日期的UTC起止时间 const targetDate = '2021-05-10'; const startOfDay = moment.utc(targetDate).startOf('day').toDate(); const endOfDay = moment.utc(targetDate).endOf('day').toDate(); const temp = await Employee.aggregate([ { $unwind: { path: '$timeClocks', preserveNullAndEmptyArrays: true }, }, { $match: { _id: { $in: employees }, // 新增日期筛选,匹配拆分后的单条打卡记录 'timeClocks.start_time': { $gte: startOfDay, $lte: endOfDay } }, }, { $group: { _id: '$_id', name: { $first: '$name' }, // 不用$push,直接$first取符合条件的单条记录,得到对象而非数组 timeClock: { $first: { start_time: '$timeClocks.start_time', end_time: '$timeClocks.end_time', } }, }, }, { $project: { name: 1, timeClock: 1, }, }, ]);
如果同一员工当天可能有多条打卡记录,你想要保留所有符合的记录但还是返回数组的话,把$group里的$first改回$push即可,筛选阶段逻辑不变。
内容的提问来源于stack exchange,提问作者DonKim
相关产品推荐
相关产品推荐

