MongoDB中$graphLookup与$lookup的选择及层级数据聚合实现
嘿,刚好能帮你理清这俩MongoDB聚合操作符的区别,还能直接给你搞定数据嵌套的方案~
先搞懂$lookup vs $graphLookup的适用场景
- $lookup:是平级关联工具,适合处理一对一、一对多的非层级关系(比如订单关联用户信息),只能关联一层数据,没法递归查询子节点的子节点。
- $graphLookup:是层级/递归关联工具,专门用来处理树形结构数据(比如部门层级、商品分类目录),可以递归查询任意层级的后代节点,直到没有子节点为止。
针对你的需求:用$lookup快速实现两层嵌套
你的数据只有两层(根节点parentId=0,子节点直接关联根节点的cid),用$lookup就足够简单高效,直接看聚合代码:
// 替换成你的集合名称,比如叫categories db.categories.aggregate([ // 第一步:先筛选出所有根节点(parentId为0的文档) { $match: { parentId: 0 } }, // 第二步:关联子节点,把匹配到的子文档放入children数组 { $lookup: { from: "categories", // 要关联的集合名称,和当前集合一致 localField: "cid", // 当前文档用来匹配的字段(父节点的cid) foreignField: "parentId", // 关联集合中用来匹配的字段(子节点的parentId) as: "children" // 存储子文档的字段名,就是你要的children } } ])
执行这段代码后,就能得到你想要的结果:每个根节点都会带上对应的子节点数组,完全符合你的预期。
如果是多层树形结构?用$graphLookup递归查询
假设你的数据不止两层(比如cid=11还有子节点parentId=11),这时候$lookup就不够用了,得用$graphLookup来递归捞所有后代:
db.categories.aggregate([ { $match: { parentId: 0 } }, { $graphLookup: { from: "categories", startWith: "$cid", // 递归的起始值:当前根节点的cid connectFromField: "cid", // 每一层递归时,用来匹配下一级的字段(当前节点的cid) connectToField: "parentId", // 下一级节点中用来匹配的字段(子节点的parentId) as: "children", // 存储所有后代节点的数组 maxDepth: 2 // 可选:指定最大递归深度,避免无限递归;不写则默认递归到没有子节点 } } ])
这个操作会把根节点下所有层级的子节点都捞出来放到children数组里,适合复杂的树形结构场景。
内容的提问来源于stack exchange,提问作者liees
相关产品推荐
相关产品推荐

