Поиск и объединение нескольких коллекций

#mongodb #mongodb-query #aggregation-framework

#mongodb #mongodb-запрос #структура агрегации

Вопрос:

Допустим, у меня есть три коллекции в базе данных IAM.

iam.policies
iam.resourceHierarchy
iam.roles

Структура документов в этих коллекциях моделируется следующим образом:

iam.policies — содержит документы, которые определяют, какие разрешения или набор разрешений (ролей) один или несколько участников имеют для данного ресурса. Каждый документ структурирован следующим образом:

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

например

 {
  'resourceID': 'program1',
  'bindings': [
    {'members': ['user/user1@example.com'], permissions: ['projects.view']},
    {'members': ['user/user2@example.com'], role: ObjectId('role1')}
  ]
}
  

role Поле в привязке ссылается на роль, определенную в iam.roles коллекции.

iam.resourceHierarchy — содержит документы, которые определяют, какие отношения являются наследственными для данного ресурса. Каждый документ структурирован следующим образом:

 {
  'resourceID': string
  'parentID': string
}
  

например

 [
  {
    'resourceID': 'program1'
  },
  {
    'resourceID': 'project1',
    'parentID': 'program1'
  }
]
  

iam.roles — содержит документы, определяющие роли, которые существуют в системе. Роль — это просто именованная абстракция поверх списка разрешений. Каждый документ в этой коллекции представляет одну роль. Например

 {
   'title': string
   'includedPermissions': [string]
}
  

например

 {
  'title': 'Program Manager',
  'includedPermissions': ['programs.view', 'programs.edit', 'projects.view', 'projects.edit']
}
  

То, что я пытаюсь сделать, это рекурсивно выполнить поиск цепочки предков для данного resourceID и для каждого из предков (включая самого resourceID себя) получить политику (например, массив привязок из iam.policies документов) и объединить их все вместе.

Я использовал эту $graphLookup функцию для получения наследственной цепочки

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

Но у меня возникли проблемы с тем, что делать дальше. Каков наилучший способ, как часть агрегации, теперь выполнить поиск bindings для каждого из предков из iam.policies коллекции?

Я изучил $lookup функцию, но мне не удалось заставить ее правильно присоединиться к bindings полю коллекции политик.

 {
  'from': 'policies',
  'startWith': '$resourceID',
  'connectFromField': 'ancestors.resourceID',
  'connectToField': 'bindings',
  'as': 'bindings'
}
  

выходные данные (например, для проекта 1)

 {
  'resourceID': 'project1',
  'parentID': 'program1',
  'ancestors': [
    {'resourceID': 'program1'},
    {'resourceID': 'project1', 'parentID': 'program1'}
  ],
  'bindings': []
}
  

У кого-нибудь есть какие-либо рекомендации или хорошие примеры этого?

Комментарии:

1. Если вы спрашиваете, как объединить graphlookup с $lookup, добавьте результаты graphlookup к вопросу и покажите, как вы используете $lookup с простым вводом.

2. Я добавил несколько примеров для ввода и вывода.

3. Вы нашли решение?