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

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 } }
])

代码分步解释

  1. $match阶段:精准定位所有直接包含用户"a"的群组(这里就是_id: "3"的文档),作为递归的起始节点。
  2. $graphLookup阶段:
    • startWith: "$_id":从直接包含用户的群组ID开始遍历
    • connectFromField: "_id":将当前群组的ID作为匹配依据
    • connectToField: "groups":匹配其他文档的groups字段(即找哪些父群组包含了当前群组)
    • 最终parentGroups会得到所有向上递归的父群组(这里就是_id: "1"的文档)
  3. $project阶段:把直接关联的群组ID和父群组ID数组合并,得到完整的候选列表。
  4. $unwind + $group阶段:展开数组后用$addToSet去重,确保结果无重复群组ID。

执行后返回结果:

{ "allGroupsIds" : [ "3", "1" ] }

原查询问题说明

你原查询的startWith: "$allGroups._id"是错误的,因为allGroups在执行$graphLookup时还未生成;同时遍历方向是向下查找子群组,和我们需要的向上找父群组的需求完全相反,所以只能拿到直接包含用户的群组。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.30 18:01:18