The field selector parameter is limited to complete properties. It cannot be used to select part of an array, only the entire array. I tried using the $ positional operator, but that didn't work.
The easiest way is to just filter the shapes in the client.
If you really need the correct output directly from MongoDB, you can use a map-reduce to filter the shapes.
function map() {
filteredShapes = [];
this.shapes.forEach(function (s) {
if (s.color === "red") {
filteredShapes.push(s);
}
});
emit(this._id, { shapes: filteredShapes });
}
function reduce(key, values) {
return values[0];
}
res = db.test.mapReduce(map, reduce, { query: { "shapes.color": "red" } })
db[res.result].find()
manpreet
Best Answer
2 years ago
Retrieve only the queried element in an object array in MongoDB collection
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?