如何在MongoDB聚合中关联users集合替换assignedPeople的ID为用户文档
MongoDB聚合查询修改方案:替换
levelOne.assignedPeople的用户ID为用户文档 修改后的完整聚合查询如下:
db.parentepics.aggregate([ // 原有第一阶段:过滤符合条件的父epic { $match: { ideaId: "616bffd81a9c715679374b19", isDeleted: false, isHidden: false, isRemovedByOwner: false, }, }, // 原有第二阶段:关联一级子任务表 { $lookup: { from: "childtasklevelones", localField: "_id", foreignField: "parentEpicId", as: "level_1", }, }, // 原有第三阶段:过滤包含指定负责人的子任务的父epic { $match: { "level_1.assignedPeople": ObjectId('616c00001a9c715679374b1b'), }, }, // 原有第四阶段:字段映射 { $project: { _id: 1, epicName: 1, epicDescription: 1, epicPriority: 1, startsFrom: 1, endsAt: 1, levelOne: "$level_1", }, }, // 新增第一阶段:拆分levelOne数组,方便逐个处理子任务的负责人字段 { $unwind: "$levelOne" }, // 新增第二阶段:关联users集合,替换负责人ID为用户文档 { $lookup: { from: "users", localField: "levelOne.assignedPeople", foreignField: "_id", as: "levelOne.assignedPeople" } }, // 新增第三阶段:重新合并levelOne数组,同时保留父epic的所有字段 { $group: { _id: "$_id", epicName: {$first: "$epicName"}, epicDescription: {$first: "$epicDescription"}, epicPriority: {$first: "$epicPriority"}, startsFrom: {$first: "$startsFrom"}, endsAt: {$first: "$endsAt"}, levelOne: {$push: "$levelOne"} } } ])
补充说明
- 上述写法兼容性强,适用于MongoDB 3.4及以上版本;如果使用MongoDB 5.0+,也可以通过
$lookup结合$map的写法省略$unwind和$group步骤,性能表现更优。 - 若不需要返回用户的全部字段,可在查询末尾额外新增
$project阶段,对levelOne.assignedPeople内的字段做过滤,仅保留用户名、头像等业务需要的字段。 - 若
assignedPeople中存在无效用户ID(users集合无匹配文档),这类ID会被直接过滤,若需要保留ID占位可额外调整关联逻辑。
内容的提问来源于stack exchange,提问作者Nick
相关产品推荐
相关产品推荐

