MongoDB中如何递归查询用户所属的所有群组ID
正确实现方案
你的核心问题是$graphLookup的遍历方向搞反了——你现在是向下遍历子群组,但我们需要从直接包含用户的群组出发,向上递归找所有父群组,同时保留直接关联的群组。
先看完整的聚合查询:
db.getCollection('groupstest').aggregate([ // 筛选直接包含用户"a"的群组,作为递归起点 { $match: { users: "a" } }, // 向上递归查找所有父群组(即groups字段包含当前群组_id的文档) { $graphLookup: { from: "groupstest", startWith: "$_id", connectFromField: "_id", connectToField: "groups", as: "parentGroups", maxDepth: 100 } }, // 合并直接关联群组与父群组的ID数组 { $project: { allRelatedGroups: { $concatArrays: [["$_id"], "$parentGroups._id"] } } }, // 展开数组以便去重 { $unwind: "$allRelatedGroups" }, // 去重并整理结果格式 { $group: { _id: null, allGroupsIds: { $addToSet: "$allRelatedGroups" } } }, { $project: { _id: 0, allGroupsIds: 1 } } ])
代码分步解释
- $match阶段:精准定位所有直接包含用户"a"的群组(这里就是
_id: "3"的文档),作为递归的起始节点。 - $graphLookup阶段:
startWith: "$_id":从直接包含用户的群组ID开始遍历connectFromField: "_id":将当前群组的ID作为匹配依据connectToField: "groups":匹配其他文档的groups字段(即找哪些父群组包含了当前群组)- 最终
parentGroups会得到所有向上递归的父群组(这里就是_id: "1"的文档)
- $project阶段:把直接关联的群组ID和父群组ID数组合并,得到完整的候选列表。
- $unwind + $group阶段:展开数组后用
$addToSet去重,确保结果无重复群组ID。
执行后返回结果:
{ "allGroupsIds" : [ "3", "1" ] }
原查询问题说明
你原查询的startWith: "$allGroups._id"是错误的,因为allGroups在执行$graphLookup时还未生成;同时遍历方向是向下查找子群组,和我们需要的向上找父群组的需求完全相反,所以只能拿到直接包含用户的群组。
内容的提问来源于stack exchange,提问作者user20395797
相关产品推荐
相关产品推荐

