I've been having trouble trying to query for a deeply nested subdocument while using Mongoose. My DB structure is like this:
{
"_id": "662aa6ccae109745e30dc664",
"username": "username",
"email": "email@email.com",
"lists": [
{
"_id": "662aa6dbae109745e30dc66a"
"name": "list",
"content": [
{
"_id": "662aa6eeae109745e30dc670"
"name": "product",
"quantity": 30,
"brands": [],
}
],
},
],
}
All I want is to query for the product _id ("_id": "662aa6eeae109745e30dc670" for example) and get the list and user _id("_id": "662aa6dbae109745e30dc66a" and "_id": "662aa6ccae109745e30dc664" respectively, on this example).
I've tried queryin for:
const user = await findOne({ 'lists.content._id': '662aa6eeae109745e30dc670' })
But this returns the whole user object. How can I query so it's return only the product object (since I can use the 'child.parent()' method to get the listId)
Use an aggregation pipeline so you can $unwind
each array lists
& then lists.content
. Then match on the criteria for lists.content._id
and project the fields you want.
db.collection.aggregate([
{ $unwind: "$lists" },
{ $unwind: "$lists.content" },
{
$match: {
"lists.content._id": "662aa6eeae109745e30dc670"
}
},
{
$project: {
// _id will be included anyway
list_id: "$lists._id",
content_id: "$lists.content._id"
}
},
// limit to just one doc if that's a requirement; NOT recommended
{ $limit: 1 }
])
Result:
[
{
"_id": "662aa6ccae109745e30dc664",
"content_id": "662aa6eeae109745e30dc670",
"list_id": "662aa6dbae109745e30dc66a"
}
]
If you want the _id
fields as they were nested in the original doc, use this $project
stage instead:
{
$project: {
"lists._id": 1,
"lists.content._id": 1
}
}
[
{
"_id": "662aa6ccae109745e30dc664",
"lists": {
"_id": "662aa6dbae109745e30dc66a",
"content": {
"_id": "662aa6eeae109745e30dc670"
}
}
}
]