MongoDB关联两个复杂集合:按uuid与objectId生成指定结果
MongoDB关联查询:将data与history集合按uuid+objectId关联并补充path字段
现有集合结构
data集合
{ _id: ObjectId('123'), uuid: '123abc', content: 'hello' } { _id: ObjectId('456'), uuid: '123abc', content: 'hi' }
history集合
{ _id: ObjectId('xxx'), uuid: '123abc', data: [{path: '/hello.json', objectId: '123'}, {path: '/hi.json', objectId: '456'}] }
期望结果
{ _id: ObjectId('123'), uuid: '123abc', content: 'hello', path: '/hello.json' } { _id: ObjectId('456'), uuid: '123abc', content: 'hi', path: '/hi.json' }
实现的聚合查询语句
db.data.aggregate([ // 关联history集合并筛选匹配的path { $lookup: { from: "history", let: { dataUuid: "$uuid", dataId: "$_id" }, pipeline: [ { $match: { $expr: { $eq: ["$uuid", "$$dataUuid"] } } }, { $unwind: "$data" }, { $match: { $expr: { $eq: ["$data.objectId", { $toString: "$$dataId" }] } } }, { $project: { _id: 0, path: "$data.path" } } ], as: "historyInfo" } }, // 展开关联结果数组 { $unwind: "$historyInfo" }, // 将path字段提取到根文档 { $addFields: { path: "$historyInfo.path" } }, // 移除临时字段 { $project: { historyInfo: 0 } } ])
语句逻辑说明
- $lookup阶段:通过uuid匹配对应的history文档,在内部pipeline中展开history的data数组,筛选出与当前data文档_id匹配的数组元素(注意将ObjectId转为字符串匹配),只保留需要的path字段。
- $unwind阶段:展开关联得到的临时数组,确保每个data文档对应唯一的path结果。
- $addFields阶段:将临时字段中的path提取到根文档,形成目标结构。
- $project阶段:清理临时关联字段,得到最终的文档格式。
内容的提问来源于stack exchange,提问作者RF.ZHU
相关产品推荐
相关产品推荐

