I have a Project
entity (projects
collection). Each Project
belongs to an organization represented by Project.orgId
and has an author Project.author
taken from users
collection.
I want to query the projects that belong to an organization using Mongoose, and here’s the pipeline I came up with:
Project.aggregate([
{
$match: { organization: new mongoose.Types.ObjectId("an-object-id") }
},
{
$lookup: {
from: User.collection.collectionName,
localField: "authorId",
foreignField: "_id",
as: "author",
},
/* Tried moving unset here. Doesn't work. Error: Arguments must be aggregate pipeline operators
{
"$unset": ["__v", "hash"],
},
*/
},
{
$unset: ["author.__v", "author.hash"]
}
])
The problem with this pipeline, is that instead of project.author
being an object, it turns into a single-element array.
Expected
{
"codename": "Longhorn",
"launch": 1970-01-01T00:00:00Z,
"author": {
"firstName": "John",
"lastName": "Smith"
}
}
Actual
{
"codename": "Longhorn",
"launch": 1970-01-01T00:00:00Z,
"author": [
{
"firstName": "John",
"lastName": "Smith"
}
]
}
What is the proper pipeline?
2
Answers
To deconstruct the array into multiple documents, you need the
$unwind
stage:That’s just how
$lookup
works. It will always give you an array since it can potentially match multiple documents in the other collection.You can convert the array to the first document in the array using
$addFields
in the step after.