MongoDB中如何按日期(忽略时间)查询子文档的唯一日期记录
嗨,针对你的MongoDB查询需求,我来分享两种常见场景的解决方案,你可以根据实际需求选择:
场景1:筛选出events数组中日期(忽略时间)唯一出现的事件
如果你的需求是保留那些在events数组里,忽略时间后日期只出现过一次的子文档,可以通过以下聚合管道实现:
db.yourCollection.aggregate([ // 展开events数组,方便逐个处理子文档 { $unwind: "$events" }, // 给每个事件添加仅保留日期部分的字段(忽略时分秒) { $addFields: { "events.dateOnly": { // MongoDB 5.0+推荐用$dateTrunc直接截断到日期,简洁高效 $dateTrunc: { date: "$events.date", unit: "day" } // 若MongoDB版本低于5.0,用$dateToString替代: // $dateToString: { format: "%Y-%m-%d", date: "$events.date" } } } }, // 按原文档ID和日期分组,统计每个日期在当前文档的事件中出现的次数 { $group: { _id: { docId: "$_id", date: "$events.dateOnly" }, events: { $push: "$events" }, count: { $sum: 1 } } }, // 只保留出现次数为1的日期组(即该日期在原文档中仅对应一个事件) { $match: { count: 1 } }, // 重新组装回原文档结构,保留原字段并整理筛选后的事件 { $group: { _id: "$_id.docId", user: { $first: "$user" }, event_group: { $first: "$event_group" }, uniqueDateEvents: { $push: { $first: "$events" } } } } ])
场景2:按日期(忽略时间)去重,每个日期保留一条事件
如果你的需求是对每个原文档的events数组,按日期(忽略时间)去重,每个日期仅保留一条事件(比如最早或最晚的),可以用下面的聚合管道:
db.yourCollection.aggregate([ { $unwind: "$events" }, { $addFields: { "events.dateOnly": { $dateTrunc: { date: "$events.date", unit: "day" } // 低版本替代:$dateToString: { format: "%Y-%m-%d", date: "$events.date" } } } }, // 按原文档ID和日期分组,保留每个日期的最晚事件(换成$first可保留最早的) { $group: { _id: { docId: "$_id", date: "$events.dateOnly" }, user: { $first: "$user" }, event_group: { $first: "$event_group" }, targetEvent: { $last: "$events" } } }, // 重新组装回原文档结构 { $group: { _id: "$_id.docId", user: { $first: "$user" }, event_group: { $first: "$event_group" }, deduplicatedEvents: { $push: "$targetEvent" } } } ])
小提示
- 记得把
yourCollection替换成你实际的集合名称。 - 如果你需要的是整个集合范围内的唯一日期事件(而非每个文档内部),只需调整分组的
_id,去掉docId字段即可。
内容的提问来源于stack exchange,提问作者Curious Developer
相关产品推荐
相关产品推荐

