Mongodb 多集合GraphLookup和Join

Mongodb 多集合GraphLookup和Join,mongodb,mongodb-query,aggregation-framework,Mongodb,Mongodb Query,Aggregation Framework,假设我在IAM数据库中有三个集合 iam.policies iam.resourceHierarchy iam.roles 这些集合中的文档结构建模如下: iam.policies-包含定义一个或多个成员对给定资源拥有的权限或权限集合(角色)的文档。每个文档的结构如下所示: { 'resourceID': string 'bindings': [ {'members': [string], 'permissions': [string]}, {'members': [st

假设我在IAM数据库中有三个集合

iam.policies
iam.resourceHierarchy
iam.roles

这些集合中的文档结构建模如下:

iam.policies
-包含定义一个或多个成员对给定资源拥有的权限或权限集合(角色)的文档。每个文档的结构如下所示:

{
  'resourceID': string
  'bindings': [
    {'members': [string], 'permissions': [string]},
    {'members': [string], 'role': ObjectId('<uuid>')}
  ]
}
{
  'resourceID': string
  'parentID': string
}
绑定中的
role
字段引用
iam.roles
集合中定义的角色

{
  'from': 'policies',
  'startWith': '$resourceID',
  'connectFromField': 'ancestors.resourceID',
  'connectToField': 'bindings',
  'as': 'bindings'
}
iam.resourceHierarchy
-包含定义给定资源的祖先关系的文档。每个文档的结构如下所示:

{
  'resourceID': string
  'bindings': [
    {'members': [string], 'permissions': [string]},
    {'members': [string], 'role': ObjectId('<uuid>')}
  ]
}
{
  'resourceID': string
  'parentID': string
}
比如说

{
  'resourceID': 'program1',
  'bindings': [
    {'members': ['user/user1@example.com'], permissions: ['projects.view']},
    {'members': ['user/user2@example.com'], role: ObjectId('role1')}
  ]
}
[
  {
    'resourceID': 'program1'
  },
  {
    'resourceID': 'project1',
    'parentID': 'program1'
  }
]
{
   'title': string
   'includedPermissions': [string]
}
{
  'title': 'Program Manager',
  'includedPermissions': ['programs.view', 'programs.edit', 'projects.view', 'projects.edit']
}
{
  'resourceID': 'project1',
  'parentID': 'program1',
  'ancestors': [
    {'resourceID': 'program1'},
    {'resourceID': 'project1', 'parentID': 'program1'}
  ],
  'bindings': []
}
iam.roles
-包含定义系统中存在的角色的文档。角色只是权限列表的命名抽象ontop。此集合中的每个文档都代表一个角色。比如说

{
  'resourceID': 'program1',
  'bindings': [
    {'members': ['user/user1@example.com'], permissions: ['projects.view']},
    {'members': ['user/user2@example.com'], role: ObjectId('role1')}
  ]
}
[
  {
    'resourceID': 'program1'
  },
  {
    'resourceID': 'project1',
    'parentID': 'program1'
  }
]
{
   'title': string
   'includedPermissions': [string]
}
{
  'title': 'Program Manager',
  'includedPermissions': ['programs.view', 'programs.edit', 'projects.view', 'projects.edit']
}
{
  'resourceID': 'project1',
  'parentID': 'program1',
  'ancestors': [
    {'resourceID': 'program1'},
    {'resourceID': 'project1', 'parentID': 'program1'}
  ],
  'bindings': []
}
比如说

{
  'resourceID': 'program1',
  'bindings': [
    {'members': ['user/user1@example.com'], permissions: ['projects.view']},
    {'members': ['user/user2@example.com'], role: ObjectId('role1')}
  ]
}
[
  {
    'resourceID': 'program1'
  },
  {
    'resourceID': 'project1',
    'parentID': 'program1'
  }
]
{
   'title': string
   'includedPermissions': [string]
}
{
  'title': 'Program Manager',
  'includedPermissions': ['programs.view', 'programs.edit', 'projects.view', 'projects.edit']
}
{
  'resourceID': 'project1',
  'parentID': 'program1',
  'ancestors': [
    {'resourceID': 'program1'},
    {'resourceID': 'project1', 'parentID': 'program1'}
  ],
  'bindings': []
}

我试图做的是递归地查找给定
resourceID
的祖先链,并为每个祖先(包括
resourceID
本身)获取策略(例如,来自
iam.policies
文档的绑定数组)并将它们合并在一起

我已经使用这个函数来获取祖先链

db.resourceHierarchy.aggregate( [
   {
      $graphLookup: {
         from: "resourceHierarchy",
         startWith: "$resourceID",
         connectFromField: "parentID",
         connectToField: "resourceID",
         as: "ancestors"
      }
   }
] )
这成功地返回了祖先链。使用上面的例子,我得到了项目1的以下输出

{
  'resourceID': 'project1',
  'parentID': 'program1',
  'ancestors': [
    {'resourceID': 'program1'},
    {'resourceID': 'project1', 'parentID': 'program1'}
  ]
}
但我不知道下一步该怎么办。作为聚合的一部分,现在从
iam.policies
集合中查找每个祖先的
绑定的最佳方法是什么

我已经研究了该函数,但未能使其在policies集合的
绑定
字段上正确连接

{
  'from': 'policies',
  'startWith': '$resourceID',
  'connectFromField': 'ancestors.resourceID',
  'connectToField': 'bindings',
  'as': 'bindings'
}
输出(例如项目1)


有人对此有什么建议或好的例子吗?

如果你问如何将graphlookup与$lookup结合起来,请将graphlookup的结果添加到问题中,并演示如何使用$lookup进行简单输入。我添加了一些输入和输出示例。你找到解决方案了吗?