I am using MongoDB natively in Node (latest I believe). I have a collection of users (example object):
{
uid: 'FifUPgoJLOLz872',
email: '[email protected]',
firstname: 'Bobby',
lastname: 'Tables',
role: 'admin'
}
And a collection of roles (example object):
{
role: 'admin',
permissions: [
{
permission: 'MANAGE_DATA',
type: 'DATA',
view: true,
add: true,
update: true,
del: true
},
{
permission: 'MANAGE_DATA_ENTRY',
type: 'DATA',
view: true,
add: true,
update: true,
del: true
},
]
}
I am trying to find a specific user and return user information along with the permissions array from the role collection based on the role in the user in the user collection.
I am using this aggregate function, which is correctly finding the user object, but it is not returning the nested "user" object in the result as defined by the projection.
const data = db.collection("users");
data.aggregate([
{$match: {uid: res.locals.uid}}, //matches the user correctly
{$lookup: {from: 'roles', localField: 'role', foreignField: 'role', as: 'Roles'}},
{$unwind: '$Roles'},
{$addFields: {"permissions": '$Roles.permissions'}},
{$project:{ user:{uid: 1, email: 1, firstname: 1, lastname: 1}, permissions: 1, _id: 0}}
]).toArray(function(err, result) {
if (err)
{
console.log(err);
}
console.log(result);
});
The match is working, as 'role' is being fed into the lookup stage but for some reason it is not including it as a separate object. If I include the user fields in the projection without being nested, they come out as expected.
Actual Result:
[
{
permissions: [
[Object], [Object]
]
}
]
Expected Result:
[
{
user: {
uid: 'FifUPgoJLOLz872',
email: '[email protected]',
firstname: 'Bobby',
lastname: 'Tables',
role: 'admin'
},
permissions: [
[Object], [Object]
]
}
]
Any idea why this is?
CodePudding user response:
In your $project
clause, you are using 1. That means keeping the field. user:{uid: 1, ...
means keeping the field user.uid
, which is not present.
The correct way to achieve what you want is:
db.users.aggregate([
{
$match: {
uid: "FifUPgoJLOLz872"
}
},
//matches the user correctly
{
$lookup: {
from: "roles",
localField: "role",
foreignField: "role",
as: "Roles"
}
},
{
$unwind: "$Roles"
},
{
$project: {
user: {
uid: "$uid",
email: "$email",
firstname: "$firstname",
lastname: "$lastname",
role: "$Roles.role"
},
permissions: "$Roles.permissions",
_id: 0
}
}
])