Mongoose聚合查询中如何在lookup结果内嵌套执行lookup
Mongoose 嵌套 $lookup 实现方案
你的核心问题是:已经通过 $lookup 获取了用户关联的 todos 数组,但 todos 内部的 owner(单 ID)和 members(ID 数组)还未关联到 users 集合的完整数据。原代码中第二个 $lookup 针对根文档的 owner 字段,但用户文档本身没有这个字段,所以完全无效。
正确的聚合代码
const userAggregate = await UserModel.aggregate([ // 匹配当前用户 { $match: { _id: req.user._id } }, // 关联 todos 集合,并在内部嵌套处理 owner 和 members 的用户信息 { $lookup: { from: "todos", localField: "todos", foreignField: "_id", as: "todos", // 针对每个 todo 执行嵌套聚合 pipeline: [ // 关联 owner 对应的用户信息 { $lookup: { from: "users", localField: "owner", foreignField: "_id", as: "owner" } }, // 将 owner 数组转为单个对象(因为 owner 是单 ID) { $unwind: "$owner" }, // 关联 members 数组对应的所有用户信息 { $lookup: { from: "users", localField: "members", foreignField: "_id", as: "members" } }, // 可选:过滤用户敏感字段(如密码) { $project: { "owner.password": 0, "members.password": 0, "owner.__v": 0, "members.__v": 0 } } ] } } ]);
代码说明
- 外层 $match:直接匹配当前用户的
_id,无需多余的$or语法 - 主 $lookup:从 todos 集合获取用户关联的所有 todo,同时通过
pipeline参数对每个 todo 做嵌套处理:- 第一个内部
$lookup:根据 todo 的owner字段,从 users 集合拉取对应的用户数据,存入owner数组 $unwind:将owner数组转为单个对象(因为owner是单 ID,lookup 后默认返回数组)- 第二个内部
$lookup:根据 todo 的members数组,批量拉取对应的用户数据,直接存入members数组 - 可选
$project:过滤掉用户的敏感字段(如密码、版本号),避免返回不必要的数据
- 第一个内部
最终返回效果
处理后 todos 中的 owner 会变成完整的用户对象,members 会变成完整的用户对象数组:
{ "status": 200, "succsess": true, "user": { "_id": "647cdd81672d662c21e94780", "first_name": "XXXXXX", "last_name": "XXXXXXX", "password": "$2b$10$mznb1HCopfcvMvXchJzH6eaXIEiiFjosv430boVaiP7akbpylOsPq", "todos": [ { "_id": "6484a24fea0553dbcb619c44", "owner": { "_id": "6484a1f5ea0553dbcb619c2d", "first_name": "XXX", "last_name": "XXX" }, "title": "first reza task", "completed": false, "startAt": "2023-06-10T12:40:16.324Z", "members": [ { "_id": "647cdd81672d662c21e94780", "first_name": "XXXXXX", "last_name": "XXXXXXX" } ] } ] } }
内容的提问来源于stack exchange,提问作者syber man
相关产品推荐
相关产品推荐

