Suppose you have the following documents in my collection:
{
"_id":ObjectId("562e7c594c12942f08fe4192"),
"shapes":[
{
"shape":"square",
"color":"blue"
},
{
"shape":"circle",
"color":"red"
}
]
},
{
"_id":ObjectId("562e7c594c12942f08fe4193"),
"shapes":[
{
"shape":"square",
"color":"black"
},
{
"shape":"circle",
"color":"green"
}
]
}
Do query:
db.test.find({"shapes.color": "red"}, {"shapes.color": 1})
Or
db.test.find({shapes: {"$elemMatch": {color: "red"}}}, {"shapes.color": 1})
Returns matched document (Document 1), but always with ALL array items in shapes
:
{ "shapes":
[
{"shape": "square", "color": "blue"},
{"shape": "circle", "color": "red"}
]
}
However, I'd like to get the document (Document 1) only with the array that contains color=red
:
{ "shapes":
[
{"shape": "circle", "color": "red"}
]
}
How can I do this?
Best Answer
MongoDB 2.2's new
$elemMatch
projection operator provides another way to alter the returned document to contain only the first matchedshapes
element:Returns:
In 2.2 you can also do this using the
$ projection operator
, where the$
in a projection object field name represents the index of the field's first matching array element from the query. The following returns the same results as above:MongoDB 3.2 Update
Starting with the 3.2 release, you can use the new
$filter
aggregation operator to filter an array during projection, which has the benefit of including all matches, instead of just the first one.Results: