MongoDB聚合查询无法过滤root类型子文档问题排查
问题分析与解决办法
你的查询失效的原因是最后一个$match阶段的逻辑不对:
"output.nodeType": {$in: ["measure"]}这个条件的作用是保留那些output数组中至少有一个元素nodeType为"measure"的文档,它只会筛选整个文档是否保留,不会修改output数组的内容,所以数组里的"root"元素依然会存在。
两种修正方案
方案一:查询后过滤数组元素
在$lookup之后,用$addFields结合$filter操作符直接清洗output数组,移除nodeType为"root"的元素:
[ { $match: { nodeType: "wave", "nodeAttributes.name.simpleValue": "wave1", "nodeAttributes.countries.simpleValue.name": "Brazil" } }, { $lookup: { from: "node", localField: "_id", foreignField: "nodeAttributes.wave.complexValue", as: "output" } }, { $addFields: { output: { $filter: { input: "$output", as: "item", cond: { $ne: ["$$item.nodeType", "root"] } } } } }, // 可选:如果要去掉output为空的文档,加上这个阶段 { $match: { "output.0": { $exists: true } } } ]
方案二:关联时直接过滤(性能更优)
在$lookup内部使用子管道,关联时就只查询nodeType不是"root"的文档,避免后续再处理冗余数据:
[ { $match: { nodeType: "wave", "nodeAttributes.name.simpleValue": "wave1", "nodeAttributes.countries.simpleValue.name": "Brazil" } }, { $lookup: { from: "node", let: { waveId: "$_id" }, pipeline: [ { $match: { $expr: { $and: [ { $eq: ["$nodeAttributes.wave.complexValue", "$$waveId"] }, { $ne: ["$nodeType", "root"] } ] } } } ], as: "output" } }, // 可选:过滤空output的文档 { $match: { "output.0": { $exists: true } } } ]
方案二更推荐,因为它在数据查询阶段就过滤掉了不需要的内容,减少了内存占用和后续处理的开销。
内容的提问来源于stack exchange,提问作者Pushpak
相关产品推荐
相关产品推荐

