Reputation: 357
Suppose I have a document:
{
"_id": "123",
"fruit": {
"apple": {
"species": "Malus pumila",
"taste": "Not bad"
},
"orange": {
"species": "Citrus sinensis",
"taste": "Pretty good"
}
}
}
I would like to do something along the lines of db.food.find({}, {"fruit.*.taste": 0})
to not include the taste field in the query results:
{
"_id": "123",
"fruit": {
"apple": {
"species": "Malus pumila"
},
"orange": {
"species": "Citrus sinensis"
}
}
}
Is such a thing possible either through a traditional query or the aggregation pipeline?
Upvotes: 3
Views: 3348
Reputation: 14476
There currently isnt a way to exclude on a wildcard on the subdocument. however, you could use the aggregation pipeline with a few $project
pipelines and the $objectToArray
and $arrayToObject
operators to achive the same result:
db.test.aggregate([
{ $project: { "fruit" : { $objectToArray: "$fruit" } } },
{ $project: { "fruit.v.taste" : 0} },
{ $project: { "fruit" : { $arrayToObject: "$fruit"} } }
]);
{
"_id" : "123",
"fruit" : {
"apple" : {
"species" : "Malus pumila"
},
"orange" : {
"species" : "Citrus sinensis"
}
}
}
The first $project { "fruit" : { $objectToArray: "$fruit" } }
converts the fruit
document to a key/value array:
{
"_id" : "123",
"fruit" : [
{
"k" : "apple",
"v" : {
"species" : "Malus pumila",
"taste" : "Not bad"
}
},
{
"k" : "orange",
"v" : {
"species" : "Citrus sinensis",
"taste" : "Pretty good"
}
}
]
}
Once we've got it in an array format we can just exclude the taste
field with a standard projection excluding the field { $project: { "fruit.v.taste" : 0} }
:
{
"_id" : "123",
"fruit" : [
{
"k" : "apple",
"v" : {
"species" : "Malus pumila"
}
},
{
"k" : "orange",
"v" : {
"species" : "Citrus sinensis"
}
}
]
}
Then we can just build back up the document using the $arrayToObject
operator.
More info can be found here: $arrayToObject - https://docs.mongodb.com/manual/reference/operator/aggregation/arrayToObject/ $objectToArray - https://docs.mongodb.com/manual/reference/operator/aggregation/objectToArray/
Upvotes: 4