使用MongoDB聚合框架替换嵌套文档数组中的关联文档
MongoDB聚合实现嵌套数组中UID替换为关联文档
针对这种多层嵌套(countries -> cities -> districts -> products)的结构,直接用$lookup确实无法直接处理,得通过逐层展开嵌套数组→关联产品数据→重新组装嵌套结构的步骤来实现,完整聚合查询代码如下:
db.Shops.aggregate([ // 第一层:展开countries数组 { $unwind: "$countries" }, // 第二层:展开countries下的cities数组 { $unwind: "$countries.cities" }, // 第三层:展开cities下的districts数组 { $unwind: "$countries.cities.districts" }, // 关联Products集合,把districts里的products UID数组换成对应文档 { $lookup: { from: "Products", localField: "$countries.cities.districts.products", foreignField: "uid", as: "productsDocs" } }, // 替换districts里的products字段为关联到的产品文档 { $set: { "countries.cities.districts.products": "$productsDocs" } }, // 移除临时的productsDocs字段 { $unset: "productsDocs" }, // 第一步组装:按店铺ID、国家、城市分组,重组districts数组 { $group: { _id: { shopId: "$_id", shopName: "$name", countryName: "$countries.name", cityName: "$countries.cities.name" }, districts: { $push: "$countries.cities.districts" } } }, // 第二步组装:按店铺ID、国家分组,重组cities数组 { $group: { _id: { shopId: "$_id.shopId", shopName: "$_id.shopName", countryName: "$_id.countryName" }, cities: { $push: { name: "$_id.cityName", districts: "$districts" } } } }, // 第三步组装:按店铺ID分组,重组countries数组,还原店铺结构 { $group: { _id: "$_id.shopId", name: { $first: "$_id.shopName" }, countries: { $push: { name: "$_id.countryName", cities: "$cities" } } } }, // 可选:保持原始文档的_id字段展示格式(不需要可删除) { $project: { _id: 1, name: 1, countries: 1 } } ])
步骤说明:
- 逐层
$unwind:把多层嵌套的数组依次展开,让每个district成为独立的文档片段,这样才能让$lookup准确匹配对应的产品UID。 $lookup关联:通过districts中的products UID数组,匹配Products集合的uid字段,将对应产品文档存入临时字段productsDocs。- 字段替换与清理:把
districts原有的UID数组替换为关联到的产品文档,再删除临时字段。 - 逐层
$group重组:从最内层的districts开始,依次向上组装cities、countries数组,最终还原整个店铺的嵌套结构。
执行该聚合管道后,就能得到你期望的结果——所有嵌套的products UID都会被替换为Products集合中的实际文档。
内容的提问来源于stack exchange,提问作者Lucien Chardon
相关产品推荐
相关产品推荐

