You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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
        }
    }
])

关键说明

  1. 第一个$lookup的结果是数组类型,必须用$unwind展开后,才能访问其中的schoolId字段
  2. 建议把第一个$lookup的as命名为studentInfo,避免和原studentnumber字段冲突,代码更清晰
  3. 最后用$project筛选并重排字段,得到和期望一致的输出结构

内容的提问来源于stack exchange,提问作者Rajesh Barik

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.19 23:15:42