在MongoDB中-尝试在2个集合之间执行递归查找,其中1个集合在该集合中具有嵌套关系

fhity93d  于 2023-01-25  发布在  Go
关注(0)|答案(1)|浏览(108)

场景是我有两个集合--一个有用户列表,一个有组列表。

"users": [
    {
      "_id": 1,
      "username": "Fred Smith",
      "level": 12,
    },
    {
      "_id": 2,
      "username": "Bob Brown",
      "level": 20,
    },
    {
      "_id": 3,
      "username": "Joe Blogs",
      "level": 1
    }
  ],

一个组拥有一个用户列表,但重要的是,它还可能在同一个列表中拥有多个组。

"groups": [
    {
      "_id": 1,
      "groupname": "admin",
      "members": ["Fred Smith"]
    },
    {
      "_id": 2,
      "groupname": "users",
      "members": [
        "Fred Smith",
        "Bob Brown",
        "contractors"
      ]
    },
    {
      "_id": 3,
      "groupname": "contractors",
      "members": ["Joe Blogs"]
    },
   {
      "_id": 4,
      "groupname": "all",
      "members": ["users"]
    }]

给定一个特定用户名的查询,我需要返回该用户所属的所有组。
到目前为止,我已经在下面的游戏中使用了$graphLookup--但是我不确定下一步要考虑用户列表中嵌套的组名,也有可能这些组会嵌套更多的组。

db.users.aggregate([
  {
    $match: {
      "username": "Joe Blogs"
    }
  },
  {
    "$graphLookup": {
      "from": "groups",
      "startWith": "$username",
      "connectFromField": "username",
      "connectToField": "members",
      "as": "groups",
      "maxDepth": 10
    }
  },
  {
    $project: {
      "username": 1,
      "groups": "$groups.groupname"
    }
  }
]

https://mongoplayground.net/p/GBRJp42bdjt

[
  {
    "_id": 3,
    "groups": [
      "contractors"
    ],
    "username": "Joe Blogs"
  }
]

在本示例中,我查询了Fred,他是contractors组的成员,但contractors组也是users组的成员,而users组是all组的成员。
因此,我需要查询返回contractors(现在是这样)以及usersall
感觉就像在这个查询中给定了一个初始的组数组,然后我需要对这个组数组执行一个不同的查询,以找出它们是哪个组的成员。
我可以修改结构,如果需要,使这更容易,但组的嵌套是一个要求。
任何帮助都感激不尽。
作为一个更新,我创建了另一个查询,给定一个组数组,它将返回所有嵌套组的规范化列表-https://mongoplayground.net/p/9NGG_wIJkGX
现在我只需要解决如何将第一个查询的结果传递给第二个查询-如果有人有想法,我将不胜感激。

crcmnpdw

crcmnpdw1#

第一个游戏场其实已经很近了,只需要在$graphLookup中使用groupname in connectFromField遍历集合,在$project的最后一个阶段,使用$reduce$setUnion$graphLookup结果中提取所有的组。

db.users.aggregate([
  {
    $match: {
      "username": "Joe Blogs"
    }
  },
  {
    "$graphLookup": {
      "from": "groups",
      "startWith": "$username",
      "connectFromField": "groupname",
      "connectToField": "members",
      "as": "groups",
      "maxDepth": 10
    }
  },
  {
    $project: {
      "username": 1,
      "groups": {
        "$reduce": {
          "input": "$groups",
          "initialValue": [],
          "in": {
            "$setUnion": [
              "$$value",
              [
                "$$this.groupname"
              ]
            ]
          }
        }
      }
    }
  }
])

Mongo Playground

相关问题