MongoDB聚合查询:如何返回单个唯一itemId的文档?
解决MongoDB聚合查询筛选同一itemId文档的问题
你的需求是筛选出同时满足两组widgetId+value条件的同一个itemId对应的所有文档,原查询仅捞取了符合任一条件的文档,因此会混入只满足单个条件的itemId数据。可以通过以下聚合步骤实现需求:
完整聚合查询
db.collection.aggregate([ // 第一步:筛选出符合任一条件的文档(保留原查询的匹配逻辑) { $match: { $or: [ { widgetId: ObjectId("669bdbd203fbdb780ed314cd"), value: "648d6d0f221f77c425aac3b9" }, { widgetId: ObjectId("669bdbd203fbdb780ed314d0"), value: "approved" } ] } }, // 第二步:按itemId分组,收集文档并统计两组条件的满足次数 { $group: { _id: "$itemId", docs: { $push: "$$ROOT" }, countCond1: { $sum: { $cond: [ { $and: [ { $eq: ["$widgetId", ObjectId("669bdbd203fbdb780ed314cd")] }, { $eq: ["$value", "648d6d0f221f77c425aac3b9"] } ] }, 1, 0 ] } }, countCond2: { $sum: { $cond: [ { $and: [ { $eq: ["$widgetId", ObjectId("669bdbd203fbdb780ed314d0")] }, { $eq: ["$value", "approved"] } ] }, 1, 0 ] } } } }, // 第三步:仅保留同时满足两组条件的itemId分组 { $match: { countCond1: { $gte: 1 }, countCond2: { $gte: 1 } } }, // 第四步:展开分组的文档数组,恢复单文档结构 { $unwind: "$docs" }, // 第五步:替换根节点,返回原始文档格式 { $replaceRoot: { newRoot: "$docs" } } ])
步骤说明
- 初始$match:先过滤出符合两组条件之一的文档,缩小后续处理的数据范围。
- $group分组:按
itemId聚合,同时统计每个itemId下满足两组条件的文档数量,确保该itemId同时包含两组条件的文档。 - 二次$match筛选:剔除仅满足单个条件的
itemId分组,只保留同时符合两组条件的分组。 - $unwind + $replaceRoot:将分组后收集的文档数组展开,恢复为原始的文档结构。
如果你的业务场景中,每个itemId对应每个条件最多只有一个文档,也可以简化分组后的判断逻辑(比如直接判断$size: "$docs"等于2),上述写法更通用,可兼容同一itemId下同一条件存在多个文档的情况。
内容的提问来源于stack exchange,提问作者user3384985
相关产品推荐
相关产品推荐

