[
{
"_id": "grandParentId",
"types": [
{
"_id": "parentId",
"files": [
{
"url": "1.example.com",
"_id": "1childId"
},
{
"url": "2.example.com",
"_id": "2childId"
}
]
}
]
}
]
cond: { _id: 2childId }
expected output: { "url": "2.example.com", "_id": "2childId" }
question 2: is this a good approach or should I just use loops to get the desired output?
CodePudding user response:
useing aggregate $unwind
and $project
test it at mongoPlayground
db.collection.aggregate([
{
"$unwind": "$types"
},
{
"$unwind": "$types.files"
},
{
"$match": {
"types.files._id": "2childId"
}
},
{
"$project": {
"url": "$types.files.url",
"_id": "$types.files._id"
}
}
])
CodePudding user response:
I'm sure that there are other ways, but you can use mongo aggregation framework:
db.collection.aggregate([
{
$match: {
"types.files._id": "2childId"
}
},
{
$unwind: "$types"
},
{
$unwind: "$types.files"
},
{
$replaceRoot: {
newRoot: "$types.files"
}
},
{
$match: {
_id: "2childId"
}
}
])
The first $match
is just to filter documents which match with your condition. $unwind
are used two times to deconstruct the different arrays. $replaceRoot
replaces the input document with the specified document (in this case subdocument, files
) and final $match
filters files
arrays that we deconstructed previously, based on your condition. First $match
is just for performance reasons, you can delete it if you want.
You can see how stages works in https://mongoplayground.net/p/hoz24xP_BNV
See mongo aggregation framework documentation if you want to learn more about it (https://docs.mongodb.com/manual/aggregation/)