如何在MongoDB聚合中结合文档字段值使用$elemMatch查询?
问题根源
常规$match阶段的查询条件默认做常量匹配,你写的nome: "$nome"会被识别为匹配nome等于字符串"$nome"的记录,不会解析为当前文档的nome字段值,因此无法得到正确结果。
解决方案
方案1:在原有结构基础上修改最后一层$match
使用$expr操作符开启字段引用能力,配合数组遍历操作实现和$elemMatch等效的过滤逻辑:
[ { $match: { nome: "Banana" } }, { $lookup: { from: 'planejamentos', localField: '_id', foreignField: 'receitas._id', as: 'planejamentos' } }, { $match: { $expr: { $gt: [ { $size: { $filter: { input: "$planejamentos", cond: { $anyElementTrue: { $map: { input: "$$this.receitas", in: { $and: [ { $eq: ["$$this.nome", "$nome"] }, { $eq: ["$$this.refeicao", "Café da Manhã"] } ] } } } } } } }, 0 ] } } } ]
方案2(更推荐):使用带管道的$lookup,关联时直接过滤
将过滤逻辑下沉到$lookup的子管道中,减少后续阶段处理的数据量,执行效率更高:
[ { $match: { nome: "Banana" } }, { $lookup: { from: "planejamentos", // 把当前食谱的字段传入子管道 let: { current_receita_id: "$_id", current_receita_nome: "$nome" }, pipeline: [ { $match: { $expr: { $and: [ // 等效原来的外键匹配 { $in: ["$$current_receita_id", "$receitas._id"] }, // 匹配餐次和名称要求 { $anyElementTrue: { $map: { input: "$receitas", in: { $and: [ { $eq: ["$$this.nome", "$$current_receita_nome"] }, { $eq: ["$$this.refeicao", "Café da Manhã"] } ] } } } } ] } } } ], as: "planejamentos" } }, // 可选:如果需要过滤掉没有匹配到计划的食谱,保留下面的阶段 { $match: { "planejamentos.0": { $exists: true } } } ]
内容的提问来源于stack exchange,提问作者RobertoOSantos
相关产品推荐
相关产品推荐

