mongodb Mongo -以传递方式查找用户的所有组ID

4smxwvx5  于 2023-03-01  发布在  Go
关注(0)|答案(1)|浏览(107)

鉴于以下文件:

{ _id : "1", groups : [ "2", "3" ] }
{ _id : "2", groups : [  ] }
{ _id : "3", groups : [ "4" ], users : [ "a" ] }
{ _id : "4", groups : [ ] }

我想找到用户“a”所属的所有组,所以查询结果应该是13,因为组1包含组3(其中包含用户),而组3直接包含用户。
我考虑过使用graphLookup,但这行不通,因为我不知道哪些组可能包含该用户。理论上,我考虑过类似这样的方法:

  • 对于每个组,传递地找到用户“a”。
  • 如果匹配,则返回进程中的所有组ID。
  • 结尾很明显。

我不知道如何在Mongo中实现这样的功能,也不知道我的理论是否正确。这是我目前所做的,但它只返回直接包含用户的组:

db.getCollection('groupstest').aggregate([
  {
    $graphLookup: {
      from: "groupstest",
      startWith: "$allGroups._id",
      connectFromField: "groups",
      connectToField: "_id",
      as: "allGroups",
      maxDepth: 100,
    },
  },
  { $unwind: "$allGroups" },
  { $match: { "allGroups.users": "a" } },
  {
    $group: {
      _id: null,
      allGroupsIds: { $addToSet: "$allGroups._id" },
    },
  },
  { $project: { _id: 0, allGroupsIds: 1 } },
]);
nx7onnlm

nx7onnlm1#

也许我们可以“倒着”思考,我们可以从包含用户a的组开始,然后,我们可以$graphLookup回到包含那些组的父组,使用$reduce迭代查找结果,并使用$setUnion将路径放入一个数组中。

db.groupstest.aggregate([
  {
    $match: {
      users: "a"
    }
  },
  {
    "$graphLookup": {
      "from": "groupstest",
      "startWith": "$_id",
      "connectFromField": "_id",
      "connectToField": "groups",
      "as": "allGroups",
      "maxDepth": 100
    }
  },
  {
    $project: {
      _id :0,
      allGroups: {
        "$reduce": {
          "input": "$allGroups",
          "initialValue": [
            "$_id"
          ],
          "in": {
            $setUnion: [
              "$$value",
              [
                "$$this._id"
              ]
            ]
          }
        }
      }
    }
  }
])

Mongo Playground

相关问题