#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. Вы нашли решение?