mongoose – 通过标准查找子文档

我刚刚陷入这个问题。 我有两个mongoose模式:

var childrenSchema = mongoose.Schema({ name: { type: String }, age: { type: Number, min: 0 } }); var parentSchema = mongoose.Schema({ name : { type: String }, children: [childrenSchema] }); 

问题是,如何从每个父文档中获取所有子文档(在本例中为childrenSchema对象)? 假设我有一些数据:

 var parents = [ { name: "John Smith", children: [ { name: "Peter", age: 2 }, { name: "Margaret", age: 20 } ]}, { name: "Another Smith", children: [ { name: "Martha", age: 10 }, { name: "John", age: 22 } ]} ]; 

我想在一个查询中检索所有18岁以上的孩子。有没有可能? 每个答案将不胜感激,谢谢!

您可以在最近的MongoDB版本中使用$elemMatch作为查询投影操作符。 从mongo shell:

 db.parents.find( {'children.age': {$gte: 18}}, {children:{$elemMatch:{age: {$gte: 18}}}}) 

这将筛选children数组中的较小的儿童文档:

 { "_id" : ..., "children" : [ { "name" : "Margaret", "age" : 20 } ] } { "_id" : ..., "children" : [ { "name" : "John", "age" : 22 } ] } 

正如你所看到的,孩子仍然被分组在他们的父母文件中。 MongoDB查询从集合中返回文档。 您可以使用汇总框架的$unwind方法将它们拆分为单独的文档:

 > db.parents.aggregate({ $match: {'children.age': {$gte: 18}} }, { $unwind: '$children' }, { $match: {'children.age': {$gte: 18}} }, { $project: { name: '$children.name', age:'$children.age' } }) { "result" : [ { "_id" : ObjectId("51a7bf04dacca8ba98434eb5"), "name" : "Margaret", "age" : 20 }, { "_id" : ObjectId("51a7bf04dacca8ba98434eb6"), "name" : "John", "age" : 22 } ], "ok" : 1 } 

我重复$match条款的性能:第一次通过它消除父母没有至less18岁的孩子,所以$unwind只考虑有用的文件。 第二个$match删除$unwind输出不匹配, $project提升孩子的信息从子文档到顶层。

在Mongoose中,你也可以像下面这样使用优雅的.populate()函数:

 parents .find({}) .populate({ path: 'children', match: { age: { $gte: 18 }}, select: 'name age -_id' }) .exec()