$ elemMatch不能用新的mongodb 2.2吗?

在MongoDB的新版本中,我们可以使用$ elemMatch投影算子来限制查询对数组中单个匹配元素的响应。 http://docs.mongodb.org/manual/reference/projection/elemMatch/

但似乎在mongoose3没有工作,这里是例子:

{ _id: ObjectId(5), items: [1,2,3,45,4,67,9,4] } Folder.findOne({_id: Object(5)}, {$elemMatch: {$in: [1,67,9]}}) .exec(function (err, doc) { }); 

我期望得到以下文档:

 { _id: ObjectId(5), items: [1,67,9] } 

但不幸的是,我得到的是与所有项目的文件:

 { _id: ObjectId(5), items: [1,2,3,45,4,67,9,4] } 

这里的mongodb文档是误导性的,我们会让他们更新。

这就是说,你现在可以在你的投影中使用$ elemMatch,也就是你的字段select:

https://gist.github.com/3640687

另见: https : //github.com/learnboost/mongoose/issues/1085

[编辑]请求发送的文档: https : //github.com/mongodb/docs/pull/185

首先,您在$ elemMatch运算符前缺lessitems字段名称。 您的查询应阅读

 Folder.findOne({_id: Object(5)}, {items: {$elemMatch: {$in: [1,67,9]}}}) .exec(function (err, doc) { }); 

但是,这仍然不会返回所需的结果,因为正如文档中所述:

$ elemMatch投影将只匹配每个源文档的一个数组元素。

所以你只能得到如下的东西:

 { _id: ObjectId(5), items: [1] } 

我没有设置mongoose做这个节点,但你也可以得到你想要的结果在2.2使用新的聚合框架 – 这是一个例子,让你得到你想要的结果。 首先,我的示例文档如下所示:

 > db.foo.findOne() { "_id" : ObjectId("50472eb566caf6af6108de02"), "items" : [ 1, 2, 3, 45, 4, 67, 9, 4 ] } 

为了达到你想要的,我做了这个:

 > db.foo.aggregate( {$match : {"_id": ObjectId("50472eb566caf6af6108de02")}}, {$unwind : "$items"}, {$match : {"items": {$in : [1, 67, 9]}}}, {$group : {_id : "$_id", items : { $push : "$items"}}}, {$project : {_id : 0, items : 1}} ) { "result" : [ { "_id" : ObjectId("50472eb566caf6af6108de02"), "items" : [ 1, 67, 9 ] } ], "ok" : 1 } 

为了解释,我将详细地逐行:

 {$match : {"_id": ObjectId("50472eb566caf6af6108de02")}} 

这是相当明显的 – 它基本上等同于普通查询的查找条件,结果被传递到stream水线中的下一步进行处理。 这是可以使用索引等的一块

 {$unwind : "$items"} 

这将爆炸数组,创build一个文档stream,每个数组的一个元素。

 {$match : {"items": {$in : [1, 67, 9]}}} 

这第二场比赛将只返回列表中的文件,基本上将文档stream减less到三个结果集。

 {$group : {_id : "$_id", items : { $push : "$items"}}} 

我们希望我们的输出是一个数组,所以我们现在必须撤销上面的展开,我们已经select了我们想要的项目,使用_id作为组合键。 注意:如果有多个匹配,这将会有重复的值,如果你想要一个唯一的列表,你将使用$addToSet而不是$push

 {$project : {_id : 1, items : 1}} 

最后,这个投影并不是真的需要,但是我把它包括来说明function – 如果你愿意,你可以select不返回_id。

一般$ elemMatch和MongoDB都不会过滤数组中的数据。 $ elemMatch可用于匹配文档,但不会影响要返回的数据。 您只能使用filter参数(find()findOne()调用的第二个参数)包含/排除logging的字段,但不能根据某些查询input过滤结果。