MongoDB多字段应用unwind后如何按指定用户的嵌套date字段排序文档
解决方案
核心实现无需多次执行$unwind,多次拆分数组会产生笛卡尔积,很容易导致匹配结果异常。我们可以先合并三个收件人数组,过滤出目标用户的记录,提取对应时间作为排序字段即可,实现效率更高也更稳定。
以下是目标邮箱为test2@gmail.com的完整聚合查询代码:
db.collection.aggregate([ // 新增临时字段存储目标用户的匹配记录 { $addFields: { targetUserRecords: { $filter: { // 合并to/cc/bcc三个收件人数组 input: { $setUnion: ["$to", "$cc", "$bcc"] }, // 过滤出邮箱匹配的用户记录 cond: { $eq: ["$$this.email_id", "test2@gmail.com"] } } } } }, // 可选步骤:过滤掉不包含目标用户的邮件文档 { $match: { targetUserRecords: { $ne: [] } } }, // 提取排序用的时间字段,按最新时间排序用$max,按最早时间排序替换为$min即可 { $addFields: { sortDate: { $max: "$targetUserRecords.date" } } }, // 按时间排序,-1为降序(最新邮件在前),1为升序(最早邮件在前) { $sort: { sortDate: -1 } }, // 移除临时字段,返回原始文档结构 { $unset: ["targetUserRecords", "sortDate"] } ])
以上述示例数据为例,执行查询后降序排序会返回Email 2在前、Email 1在后的结果,完全匹配test2@gmail.com在两个文档中的对应时间排序逻辑。如果用户同时出现在to/cc/bcc多个分区,可根据业务需求调整$max/$min操作符选择对应排序时间即可。
内容的提问来源于stack exchange,提问作者Ram
相关产品推荐
相关产品推荐

