You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

MongoDB多集合嵌套关联查询:distributors关联fruits与tools

解决方案:MongoDB深层嵌套集合链式关联聚合查询

针对你需要将distributors、fruits、tools三个集合做深层链式关联的需求,这里提供一个一次性聚合查询方案,完美处理嵌套字段的替换:

db.distributors.aggregate([
  // 第一步:关联fruits集合,同时在内部管道中先完成与tools的关联替换
  {
    $lookup: {
      from: "fruits",
      let: { distributorChildren: "$categories.children" },
      pipeline: [
        // 先把fruits关联到tools集合
        {
          $lookup: {
            from: "tools",
            localField: "variants.tools",
            foreignField: "uid",
            as: "toolsDocs"
          }
        },
        // 替换fruits里variants的tools字段为对应工具文档
        {
          $addFields: {
            variants: {
              $map: {
                input: "$variants",
                as: "variant",
                in: {
                  $mergeObjects: [
                    "$$variant",
                    {
                      tools: {
                        $map: {
                          input: "$$variant.tools",
                          as: "toolUid",
                          in: {
                            $first: {
                              $filter: {
                                input: "$toolsDocs",
                                cond: { $eq: ["$$this.uid", "$$toolUid"] }
                              }
                            }
                          }
                        }
                      }
                    }
                  ]
                }
              }
            },
            fruitUid: "$uid" // 临时存uid用于后续匹配
          }
        },
        // 过滤掉distributors没用到的fruits文档
        {
          $match: {
            $expr: {
              $in: [
                "$fruitUid",
                {
                  $reduce: {
                    input: "$$distributorChildren",
                    initialValue: [],
                    in: {
                      $concatArrays: [
                        "$$value",
                        {
                          $reduce: {
                            input: "$$this.children",
                            initialValue: [],
                            in: { $concatArrays: ["$$value", ["$$this.child"]] }
                          }
                        }
                      ]
                    }
                  }
                }
              ]
            }
          }
        },
        // 清理临时字段
        { $project: { uid: 0, toolsDocs: 0 } }
      ],
      as: "mappedFruits"
    }
  },
  // 第二步:替换distributors里深层嵌套的child字段为处理后的fruits文档
  {
    $addFields: {
      categories: {
        $map: {
          input: "$categories",
          as: "category",
          in: {
            $mergeObjects: [
              "$$category",
              {
                children: {
                  $map: {
                    input: "$$category.children",
                    as: "childItem",
                    in: {
                      $mergeObjects: [
                        "$$childItem",
                        {
                          child: {
                            $first: {
                              $filter: {
                                input: "$mappedFruits",
                                cond: { $eq: ["$$this.fruitUid", "$$childItem.child"] }
                              }
                            }
                          }
                        }
                      ]
                    }
                  }
                }
              }
            ]
          }
        }
      }
    }
  },
  // 移除临时的mappedFruits字段
  { $project: { mappedFruits: 0 } }
])

核心思路说明

  • 嵌套$lookup搞定链式关联:在关联fruits的内部管道里先完成fruits与tools的替换,不用分开写多次聚合,一次搞定两层关联。
  • 深层数组处理:用$reduce+$concatArrays把distributors里所有深层的child值提取出来,确保能精准匹配到对应的fruits文档;再用$map+$filter逐个替换嵌套字段,保留原文档的其他结构不变。
  • 适配小数据量场景:因为fruits和tools最多只有10条数据,用$filter遍历完全没性能问题,不用搞复杂的索引优化。

关键步骤拆解

  1. 预处理fruits文档:先把fruits里的variants.tools替换成完整的tools文档,同时只保留distributors实际用到的那些fruits,减少后续处理的数据量。
  2. 替换distributors的child字段:遍历distributors的嵌套数组,把每个child的UID替换成预处理好的完整fruits文档,同时保留原有的分类结构。

内容的提问来源于stack exchange,提问作者Lucien Chardon

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.29 07:52:52