假設您的收藏夾中包含如下文檔: 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" } ]}