Welcome to the community, @Marcus_Lindner!
This can be achieved with this aggregation pipeline:
db.test1.aggregate([
{
// match the users, that you want to
// join permissions on other users
// (this stage can be omitted or modified as desired)
$match: {
name: 'Mauer'
}
},
{
// unwind the 'rights' array,
// so it would be possible to join only the users,
// that a given user has enough rights
$unwind: '$rights',
},
{
// filter the users to join here;
// feel free to change the matching params
$match: {
'rights.type': 'read',
'rights.level': {
$gte: 1,
}
}
},
{
$group: {
_id: '$_id',
name: {
$first: '$name',
},
rights: {
$push: '$rights',
}
}
},
{
$graphLookup: {
from: 'test1',
startWith: '$rights.to',
connectFromField: 'rights.to',
// set maxDepth to 0, so
// dependencies of the dependencies
// would not join
maxDepth: 0,
connectToField: '_id',
as: 'hasRequiredRightsOn',
}
},
{
// (optionally)
// clean-up
$project: {
rights: false,
'hasRequiredRightsOn.rights': false,
}
}
]).pretty();
Tested on the below dataset. I have prettified and reformatted it slightly, so it would be more readable and work in the mongo-shell. The data is kept untouched, though.
db.test1.insertMany([
{
_id: 1,
name: "Hugo",
rights: []
},
{
_id: 2,
name: "Hermann",
rights: [
{ to: 1, type: "write", level: 0 }
]
},
{
_id: 3,
name: "Mauer",
rights: [
{ to: 1, type: "write", level: 0 },
{ to: 2, type: "read", level: 1 }
]
},
{
_id: 4,
name: "Jon",
rights: [
{ to: 1, type: "read", level: 1 },
{ to: 2, type: "read", level: 1 }
]
},
{
_id: 5,
name: "Jane",
rights: [
{ to: 1, type: "write", level: 0 },
{ to: 3, type: "write", level: 0 },
{ to: 6, type: "read", level: 1 },
{ to: 4, type: "read", level: 1 }
]
},
{
_id: 6,
name: "Michael",
rights: [
{ to: 4, type: "read", level: 1 },
{ to: 5, type: "read", level: 1 }
]
}
]);
The output of the above aggregation will look like this (notice, that only required users are joined):
{
"_id" : 3,
"name" : "Mauer",
"hasRequiredRightsOn" : [
{
"_id" : 2,
"name" : "Hermann"
}
]
}
You can include additional fields into the output with the $project stage.