MongoDB关联查询:如何仅从关联集合获取指定字段并保留原字段
这个问题的核心是你用了$project的白名单模式,导致原集合的字段都被过滤掉了——MongoDB的$project默认只保留你明确指定的字段,所以你只拿到了foobar。下面给你几种简单的解决方案,都能实现保留Collection_foo全部字段+新增foobar的需求:
方案1:用$addFields替代$project(最推荐)
$addFields的作用是在现有文档基础上新增字段,不会删除任何原有字段,完美匹配你的需求:
aggregate([ { $lookup: { from: 'Collection_bar', localField: 'cid', foreignField: 'cid', as: 'collection_foo_bar' } }, { $unwind: '$collection_foo_bar' }, // 展开关联数组(如果每个cid唯一匹配,这步可以保留) { $addFields: { 'foobar': '$collection_foo_bar.foobar' } }, { $project: { collection_foo_bar: 0 } } // 移除临时的关联数组字段 ])
方案2:处理多匹配场景(避免$unwind生成重复文档)
如果Collection_bar中同一个cid可能对应多个文档,$unwind会让结果变成多条重复的Collection_foo记录(每条对应一个关联的Collection_bar文档)。这时候可以用$arrayElemAt直接取第一个匹配的foobar,跳过$unwind:
aggregate([ { $lookup: { from: 'Collection_bar', localField: 'cid', foreignField: 'cid', as: 'collection_foo_bar' } }, { $addFields: { 'foobar': { $arrayElemAt: ['$collection_foo_bar.foobar', 0] } } }, { $project: { collection_foo_bar: 0 } } ])
方案3:用$replaceRoot合并文档(另一种思路)
如果你偏好重构文档结构,可以通过$mergeObjects把原文档和foobar字段合并:
aggregate([ { $lookup: { from: 'Collection_bar', localField: 'cid', foreignField: 'cid', as: 'collection_foo_bar' } }, { $unwind: '$collection_foo_bar' }, { $replaceRoot: { newRoot: { $mergeObjects: [ '$$ROOT', // 引用原文档的所有字段 { 'foobar': '$collection_foo_bar.foobar' } ] } } }, { $project: { collection_foo_bar: 0 } } ])
为什么原代码没达到预期?
你原来的$project只指定了'foobar':'collection_foo_bar.foobar',并且把collection_foo_bar设为0,这相当于告诉MongoDB:"只保留foobar字段,其他都删掉"。所以原Collection_foo的所有字段都被排除了,这就是为什么结果只有foobar。
内容的提问来源于stack exchange,提问作者lowaxe
相关产品推荐
相关产品推荐

