假设您的收藏夹中包含如下文档: javascript
{ "_id":ObjectId("562e7c594c12942f08fe4192"), "shapes":[ { "shape":"square", "color":"blue" }, { "shape":"circle", "color":"red" } ] }, { "_id":ObjectId("562e7c594c12942f08fe4193"), "shapes":[ { "shape":"square", "color":"black" }, { "shape":"circle", "color":"green" } ] }
进行查询: java
db.test.find({"shapes.color": "red"}, {"shapes.color": 1})
要么 mongodb
db.test.find({shapes: {"$elemMatch": {color: "red"}}}, {"shapes.color": 1})
返回匹配的文档(文档1) ,但始终具备shapes
全部数组项: 数组
{ "shapes": [ {"shape": "square", "color": "blue"}, {"shape": "circle", "color": "red"} ] }
可是,我只想使用包含color=red
的数组来获取文档(文档1) : 框架
{ "shapes": [ {"shape": "circle", "color": "red"} ] }
我怎样才能作到这一点? ide
MongoDB 2.2+中的新聚合框架提供了Map / Reduce的替代方案。 $unwind
运算符可用于将您的shapes
数组分红可匹配的文档流: spa
db.test.aggregate( // Start with a $match pipeline which can take advantage of an index and limit documents processed { $match : { "shapes.color": "red" }}, { $unwind : "$shapes" }, { $match : { "shapes.color": "red" }} )
结果是: code
{ "result" : [ { "_id" : ObjectId("504425059b7c9fa7ec92beec"), "shapes" : { "shape" : "circle", "color" : "red" } } ], "ok" : 1 }
MongoDB 2.2的新的$elemMatch
投影运算符提供了另外一种方法来更改返回的文档以仅包含第一个匹配的shapes
元素: 对象
db.test.find( {"shapes.color": "red"}, {_id: 0, shapes: {$elemMatch: {color: "red"}}});
返回值: 索引
{"shapes" : [{"shape": "circle", "color": "red"}]}
在2.2中,您也能够使用$ projection operator
执行此$ projection operator
,其中投影对象字段名称中的$
表示查询中该字段的第一个匹配数组元素的索引。 如下返回与上面相同的结果:
db.test.find({"shapes.color": "red"}, {_id: 0, 'shapes.$': 1});
MongoDB 3.2更新
从3.2发行版开始,您能够使用新的$filter
聚合运算符在投影期间过滤数组,这样作的好处是包括全部匹配项,而不单单是第一个匹配项。
db.test.aggregate([ // Get just the docs that contain a shapes element where color is 'red' {$match: {'shapes.color': 'red'}}, {$project: { shapes: {$filter: { input: '$shapes', as: 'shape', cond: {$eq: ['$$shape.color', 'red']} }}, _id: 0 }} ])
结果:
[ { "shapes" : [ { "shape" : "circle", "color" : "red" } ] } ]
与$ project一块儿使用,更明智的作法是将其余明智的匹配元素与文档中的其余元素合并在一块儿。
db.test.aggregate( { "$unwind" : "$shapes" }, { "$match" : { "shapes.color": "red" }}, {"$project":{ "_id":1, "item":1 }} )
在mongodb中查找的语法是
db.<collection name>.find(query, projection);
和您编写的第二个查询,即
db.test.find( {shapes: {"$elemMatch": {color: "red"}}}, {"shapes.color":1})
在这种状况下,您在查询部分中使用了$elemMatch
运算符,而若是在投影部分中使用了此运算符,则将得到所需的结果。 您能够将查询记为
db.users.find( {"shapes.color":"red"}, {_id:0, shapes: {$elemMatch : {color: "red"}}})
这将为您提供所需的结果。
在这里,我只想添加一些更复杂的用法。
// Document { "_id" : 1 "shapes" : [ {"shape" : "square", "color" : "red"}, {"shape" : "circle", "color" : "green"} ] } { "_id" : 2 "shapes" : [ {"shape" : "square", "color" : "red"}, {"shape" : "circle", "color" : "green"} ] } // The Query db.contents.find({ "_id" : ObjectId(1), "shapes.color":"red" },{ "_id": 0, "shapes" :{ "$elemMatch":{ "color" : "red" } } }) //And the Result {"shapes":[ { "shape" : "square", "color" : "red" } ]}