MongoDB聚合:如何在$lookup中使用其他集合字段作为localField
MongoDB聚合查询:用关联集合的字段做$lookup的localField
集合结构示例
三个集合的文档如下:
Collection 1
{ _id: ObjectId('123'), studentnumber: 123, current_position: 'A', schoolId: ObjectId('387') }
Collection 2
{ _id: ObjectId('456'), studentId: ObjectId('123'), studentnumber: 123, firstname: 'John', lastname: 'Doe', schoolId: ObjectId('543') }
Collection 3
{ _id: ObjectId('387'), schoolName: 'Some school' }, { _id: ObjectId('543'), schoolName: 'Some other school' }
现有聚合查询
目前的聚合代码是:
db.collection1.aggregate([ { $lookup: { from: "collection2", localField: "studentnumber", foreignField: "studentnumber", as: "studentnumber", }, }, { $lookup: { from: "collection3", localField: "schoolId", foreignField: "_id", as: "schoolId", } } ])
当前输出与期望输出
当前输出
{ _id: ObjectId('123'), firstname: 'John', lastname: 'Doe', current_position: 'A', school: { _id: ObjectId('387'), schoolName: 'Some school' } }
期望输出
想要关联collection2里的schoolId,得到这样的结果:
{ _id: ObjectId('123'), firstname: 'John', lastname: 'Doe', current_position: 'A', school: { _id: ObjectId('543'), schoolName: 'Some other school' } }
解决方法
可以通过展开第一个$lookup的结果数组,再用关联集合的字段作为第二个$lookup的localField,具体修改后的聚合代码如下:
db.collection1.aggregate([ // 关联collection2,把结果存为studentInfo(避免覆盖原字段) { $lookup: { from: "collection2", localField: "studentnumber", foreignField: "studentnumber", as: "studentInfo" } }, // 展开studentInfo数组(一个学生对应一条collection2记录,展开后可直接访问内部字段) { $unwind: "$studentInfo" }, // 用collection2里的schoolId关联collection3 { $lookup: { from: "collection3", localField: "studentInfo.schoolId", foreignField: "_id", as: "school" } }, // 展开school数组 { $unwind: "$school" }, // 整理输出结构,匹配期望格式 { $project: { _id: 1, firstname: "$studentInfo.firstname", lastname: "$studentInfo.lastname", current_position: 1, school: 1 } } ])
关键说明
- 第一个$lookup的结果是数组类型,必须用
$unwind展开后,才能访问其中的schoolId字段 - 建议把第一个$lookup的
as命名为studentInfo,避免和原studentnumber字段冲突,代码更清晰 - 最后用
$project筛选并重排字段,得到和期望一致的输出结构
内容的提问来源于stack exchange,提问作者Rajesh Barik
相关产品推荐
相关产品推荐

