Reputation: 12326
I have documents like this:
{
"_id" : ObjectId("53340d07d6429d27e1284c77"),
"worktypes" : [
{
"name" : "Pompas",
"works" : [
{
"name" : "work 1",
"code" : "0001"
}
]
},
{
"name" : "Pompas "",
"works" : [
{
"name" : "work 2",
"code" : "0002"
}
]
}
]
}
I did a query for get ONLY the works of one of worktype for this document, this is the query:
db.categories.find({$and: [
{ "_id": ObjectId('53340d07d6429d27e1284c77')},
{"worktypes.name": "Pompas"}
]},{"worktypes.works.$":1})
But i got
{
"_id" : ObjectId("53340d07d6429d27e1284c77"),
"worktypes" : [
{
"name" : "Pompas",
"works" : [
{
"name" : "work 1",
"code" : "0001"
}
]
}
]
}
But i only need:
"works" : [
{
"name" : "work 1",
"code" : "0001"
}
]
How can i reduce this?
Upvotes: 1
Views: 487
Reputation: 12934
I think Neil Lunn's answer is mostly correct, but in my opinion it needs a few tweaks to get the expected result:
"worktypes.name"
rather than "worktypes.works.name"
$group
phase, use $first
instead of $push
to get the first element alone $project
phase to just get the "works"
db.categories.aggregate([
{ "$unwind": "$worktypes" },
{ "$unwind": "$worktypes.works" },
{ "$match": {
"worktypes.name": "Pompas"
}},
{ "$group": {
"_id": "$_id",
"works": { "$first": "$worktypes.works" }
}},
{ "$project": {"_id":0, "works":1} }
])
Output:
{
"result" : [
{
"works" : {
"name" : "work 1",
"code" : "0001"
}
}
],
"ok" : 1
}
Upvotes: 13
Reputation: 151162
You need to use the $unwind
operator when working with arrays:
db.catefories.aggregate([
// Unwind the first array
{ "$unwind": "$worktypes" },
// Then unwind the embedded array
{ "$unwind": "$worktypes.works" },
// Match the item you want
{ "$match": {
"worktypes.works.name": "work 1"
}},
// Group to reform the array structure
{ "$group": {
"_id": "$_id",
"worktypes": { "$push": "$worktypes" }
}}
])
And to get back as an array use $group
after the $unwind
.
Upvotes: 2
Reputation: 1374
You can selectively remove fields from the projection like so:
db.categories.find({$and: [
{ "_id": ObjectId('53340d07d6429d27e1284c77')},
{"worktypes.name": "Pompas"}
]},{"worktypes.works.$":1, _id:0 })
this will prevent the _id field from being projected.
Upvotes: 0