MongoDB聚合:关联其他集合字段,无匹配则设为null
MongoDB聚合查询问题解决
现有Schema
employeeSchema
employeeSchema: { _id: ObjectId isActive: Boolean }
careerSchema
careerSchema: { employeeId: ObjectId // 关联employeeSchema的_id isCurrentlyWorking: Boolean position: String // 职位 }
需求
查询isActive为true的员工,同时关联Career集合中该员工对应的isCurrentlyWorking为true的文档,将其position字段存入员工文档的career字段;若员工无对应Career文档或无匹配记录,需将career设为null。
尝试的聚合代码
const result = await Employee.aggregate([ { $match: { isActive: true } }, { from: "careers", localField: "_id", foreignField: "employeeId", as: "career", pipeline: [ { $match: { isCurrentlyWorking: true} }, { $project: { position: 1} } ] } ])
遇到的问题
返回结果中career字段为空数组,无法使用$unwind操作,且无对应记录时未设为null。
解决方案
修改聚合流程,在$lookup之后添加处理逻辑,将空数组转为null,同时提取匹配到的职位信息:
const result = await Employee.aggregate([ // 筛选活跃员工 { $match: { isActive: true } }, // 关联careers集合并筛选在职记录 { $lookup: { from: "careers", localField: "_id", foreignField: "employeeId", as: "career", pipeline: [ { $match: { isCurrentlyWorking: true } }, { $project: { position: 1, _id: 0 } } // 仅保留position字段 ] } }, // 处理空数组,将其转为null,否则提取第一个匹配的职位 { $addFields: { career: { $cond: { if: { $eq: ["$career", []] }, then: null, else: { $arrayElemAt: ["$career.position", 0] } } } } } ])
关键说明
- 在
$lookup的子管道中添加_id: 0,剔除不必要的_id字段,简化后续处理 - 用
$cond判断career数组是否为空:- 为空时直接赋值
null - 不为空时,通过
$arrayElemAt取出数组第一个元素的position值,确保career字段是字符串类型而非数组
- 为空时直接赋值
这样处理后,最终返回的员工文档中,career字段要么是对应的职位字符串,要么是null,完全符合需求。
内容的提问来源于stack exchange,提问作者Saurav Ghimire
相关产品推荐
相关产品推荐

