如何通过MongoDB聚合查询获取产品关联的N级层级分类
实现方案
该需求可以通过MongoDB的$graphLookup递归查询算子实现,完美适配任意N级层级的分类结构,具体聚合语句如下:
db.product.aggregate([ // 1. 关联拿到产品对应的叶子分类基础信息 { $lookup: { from: "category", localField: "category", foreignField: "_id", as: "category" } }, // 2. 拆分数组为单个对象(一个产品仅关联一个分类,无冗余数据) { $unwind: "$category" }, // 3. 递归查询所有上级分类,支持无限层级 { $graphLookup: { from: "category", startWith: "$category.parent", // 从当前分类的父ID开始递归 connectFromField: "parent", // 分类表存储父ID的字段 connectToField: "_id", // 关联分类表的主键ID as: "categoryParents", // 存储所有上级分类的数组 depthField: "depth" // 记录层级深度,用于后续排序 } }, // 4. 按层级深度排序父级数组,保证从子到父的拼装顺序 { $set: { categoryParents: { $sortArray: { input: "$categoryParents", sortBy: { depth: 1 } } } } }, // 5. 把平铺的父级数组拼装为嵌套结构,无父级则自动删除parent字段 { $set: { "category.parent": { $cond: { if: { $gt: [{ $size: "$categoryParents" }, 0] }, then: { $reduce: { input: "$categoryParents", initialValue: {}, in: { name: "$$this.name", parent: "$$value" } } }, else: "$$REMOVE" } } } }, // 6. 清理多余字段,输出目标结构 { $project: { _id: 0, name: 1, category: 1 } } ])
注意事项
- 请根据你实际的字段名调整代码中的关联字段:如果你的category集合的父级字段实际是
parentId,把上面所有的parent替换为parentId即可。 - 该方案支持任意层级的分类结构,不需要提前知晓分类层级数,递归会在匹配不到父级时自动停止。
内容的提问来源于stack exchange,提问作者Anas Alazmeh
相关产品推荐
相关产品推荐

