Mongoose聚合lookup关联ColC数据嵌入ColB列表的实现问题
问题原因
你当前的写法将所有ColB关联的ColC数据统一存放到了独立的col_c_list数组中,没有和col_b_list里的单个ColB项做绑定,所以无法直接合并到对应ColB对象中。
解决方案
方案1(推荐,MongoDB 3.6及以上版本适用)
使用嵌套$lookup管道,在查询ColB的时候直接关联对应ColC数据,合并到ColB对象中:
const list = await ColA.aggregate([ { $lookup: { from: "ColB", localField: "_id", foreignField: "colA_id", // 注意和你实际数据库的字段大小写保持一致 as: "col_b_list", // 嵌套管道给每个ColB项关联ColC pipeline: [ { $lookup: { from: "ColC", localField: "spec_id", foreignField: "_id", as: "col_c_info" } }, // 合并ColB和对应ColC的字段 { $replaceRoot: { newRoot: { $mergeObjects: [ "$$ROOT", { $first: "$col_c_info" } ] } } }, // 移除不需要的临时字段 { $unset: "col_c_info" } ] } }, // 输出你需要的格式 { $project: { _id: 1, some_other_data: 1, list: "$col_b_list" } } ]) return list
方案2(兼容低版本MongoDB)
保留你原有查询逻辑,新增字段处理阶段匹配对应ColC数据:
const list = await ColA.aggregate([ { $lookup: { from: "ColB", localField: "_id", foreignField: "colA_id", as: "col_b_list", }, }, { $lookup: { from: "ColC", localField: "col_b_list.spec_id", foreignField: "_id", as: "col_c_list", }, }, // 遍历ColB数组,给每个项匹配对应ColC数据合并 { $addFields: { list: { $map: { input: "$col_b_list", as: "b", in: { $mergeObjects: [ "$$b", { $first: { $filter: { input: "$col_c_list", as: "c", cond: { $eq: ["$$c._id", "$$b.spec_id"] } } } } ] } } } } }, // 输出需要的字段 { $project: { _id: 1, some_other_data: 1, list: 1 } } ]) return list
注意事项
如果存在ColB的spec_id没有对应ColC记录的情况,可以额外加条件判断过滤null值,避免多余的空字段。
内容的提问来源于stack exchange,提问作者hexoyin10
相关产品推荐
相关产品推荐

