Hi! I have a collection which is structured in the following way:
{
nested: {
users: [
{ user: ObjectId('...'), status: 'pending' },
{ user: ObjectId('...'), status: 'approved' },
]
}
}
I wish to use an aggregation pipeline to populate the “users” field so the document gets turned into the following:
{
nested: {
users: [
{ user: { _id: ObjectId('...'), name: 'John' }, status: 'pending' },
{ user: { _id: ObjectId('...'), name: 'Mike' }, status: 'approved' },
]
}
}
The problem is:
- I need to unwind “users” first in order to perform the lookup, so “users” will get turned into a single object
- I cannot rebuild the “users” array with the “$group” stage because “$group” doesn’t support nested fields
Some details to be considered:
- I’m using MongoDB NodeJS driver only – without tools like Mongoose
- It is important for my use case to use a single aggregation, without further JS processing
- Document must be retrieved on it’s original shape
- Reshaping the data is not an option, the data was just an example of a more general problem I’m experiencing
The pipeline I’ve got so far (doesn’t work because the “users” array gets flattened into a single document):
[
{
"$match": {
"_id":ObjectId( "66b93fc2007e4988489dfa0b")
}
},
{
"$unwind": {
"path": "$nested",
"preserveNullAndEmptyArrays": true
}
},
{
"$unwind": {
"path": "$nested.users",
"preserveNullAndEmptyArrays": true
}
},
{
"$lookup": {
"from": "users",
"let": {
"ids": "$nested.users.user"
},
"as": "nested.users.user",
"pipeline": [
{
"$match": {
"$expr": {
"$eq": [
"$_id",
"$$ids"
]
}
}
}
]
}
},
{
"$unwind": {
"path": "$nested.users.user",
"preserveNullAndEmptyArrays": true
}
},
{
"$group": {
"_id": "$_id",
"nested": {
"$first": "$nested"
}
}
}
]