如何编写MongoDB查询按指定用户关联日期排序邮件数据并解决文档遗漏
MongoDB按用户维度匹配邮件并按对应日期排序的解决方案
你现有查询的核心问题出在 $concatArrays 运算符的特性上:只要参与拼接的数组中有任意一个值为null(比如你部分文档的cc、bcc字段为null),拼接后的结果就会直接返回null,后续$unwind操作处理null值时会直接丢弃对应文档,这就是部分文档被跳过的原因。同时你的查询缺少排序步骤,也没有对同一邮件下多个匹配记录去重的逻辑,无法得到预期顺序。
修复后的完整查询如下:
db.collection.aggregate([ // 筛选所有收件人/抄送人/密送人包含test2@gmail.com的邮件 { "$match": { "$or": [ {"to.email_id": "test2@gmail.com"}, {"cc.email_id": "test2@gmail.com"}, {"bcc.email_id": "test2@gmail.com"} ] } }, // 拼接三类收件人数组,用$ifNull把null值转为空数组,避免拼接结果为null { "$project": { subject: 1, body: 1, concat: { $concatArrays: [ {$ifNull: ["$to", []]}, {$ifNull: ["$cc", []]}, {$ifNull: ["$bcc", []]} ] } } }, // 展开拼接后的收件人数组 {"$unwind": "$concat"}, // 仅保留test2@gmail.com的匹配记录 { "$match": { "concat.email_id": "test2@gmail.com" } }, // 按邮件原始_id分组,避免同一邮件出现多条匹配记录(比如test2同时在to和bcc的场景) { "$group": { "_id": "$_id", "subject": {$first: "$subject"}, "body": {$first: "$body"}, "concat": {$first: "$concat"} } }, // 按test2对应的日期升序排序 {"$sort": {"concat.date": 1}}, // 调整输出结构匹配你的预期格式 { "$project": { "_id": null, "uniqueValues": { "_id": "$_id", "body": "$body", "concat": "$concat", "subject": "$subject" } } } ])
如果同一封邮件里test2出现在不同收件人位置(to/cc/bcc)时对应日期不同,可以把$group里的$first改为$min来取最早的匹配日期,适配业务需求。
内容的提问来源于stack exchange,提问作者Shashi Pipare
相关产品推荐
相关产品推荐

