MongoDB聚合查询(含$lookup):仅返回status=1的关联成员
要解决这个问题,核心是要先过滤myCollection文档中members数组里status=1的元素,再执行关联查询——普通的$lookup会拉回所有匹配memberId的成员,不会考虑status的过滤条件。下面给你两种可行的方案:
方案一:先过滤数组再关联(直观易懂)
这种方式先把原文档里符合status=1的成员筛选出来,再基于筛选后的memberId去关联members集合:
db.getCollection('myCollection').aggregate([ { $match: { _id: ObjectId("5e8b0bac041a913bc608d69d") }}, // 过滤members数组,只保留status=1的元素 { $addFields: { filteredMembers: { $filter: { input: "$members", cond: { $eq: ["$$this.status", 1] } } } }}, // 基于过滤后的memberId关联members集合 { "$lookup": { "from": "members", "localField": "filteredMembers.memberId", "foreignField": "_id", "as": "Members" } }, { $project: { "Members.firstname": 1, "Members.lastname": 1, "Members._id": 1 } } ])
方案二:用$lookup的管道版本(无需临时字段)
这种方式直接在$lookup的子管道里完成过滤,不需要额外添加临时字段,逻辑更紧凑:
db.getCollection('myCollection').aggregate([ { $match: { _id: ObjectId("5e8b0bac041a913bc608d69d") }}, { "$lookup": { "from": "members", "let": { memberList: "$members" }, "pipeline": [ { $match: { $expr: { $and: [ // 匹配当前成员的_id在目标文档的memberId列表中 { $in: ["$_id", "$$memberList.memberId"] }, // 找到对应memberId的元素,判断其status是否为1 { $eq: [ { $arrayElemAt: [ { $filter: { input: "$$memberList", cond: { $eq: ["$$this.memberId", "$_id"] } }}, 0 ]}.status, 1 ]} ] } }} ], "as": "Members" } }, { $project: { "Members.firstname": 1, "Members.lastname": 1, "Members._id": 1 } } ])
两种方案的说明
- 方案一的逻辑更清晰,先筛选出符合条件的成员ID,再关联,适合新手理解和维护。
- 方案二则把过滤逻辑整合到关联步骤中,减少了中间字段的生成,查询效率略优(差异不大,取决于数据量)。
两种方案都能精准返回status=1的成员关联数据,你可以根据自己的习惯选择使用。
内容的提问来源于stack exchange,提问作者user2285831
相关产品推荐
相关产品推荐

