node.js Mongoose - 按标准查找子文档
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/16845191/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Mongoose - finding subdocuments by criteria
提问by Kuba T
I've just got stuck with this problem. I've got two Mongoose schemas:
我刚刚被这个问题困住了。我有两个猫鼬模式:
var childrenSchema = mongoose.Schema({
name: {
type: String
},
age: {
type: Number,
min: 0
}
});
var parentSchema = mongoose.Schema({
name : {
type: String
},
children: [childrenSchema]
});
Question is, how to fetch all subdocuments (in this case, childrenSchemaobjects) from every parent document? Let's suppose I have some data:
问题是,如何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 }
]}
];
I would like to retrieve - in a single query - all children older than 18. Is it possible? Every answer will be appreciated, thanks!
我想在单个查询中检索所有 18 岁以上的儿童。这可能吗?每个答案都将不胜感激,谢谢!
回答by A. Jesse Jiryu Davis
You can use $elemMatchas a query-projection operator in the most recent MongoDB versions. From the mongo shell:
您可以$elemMatch在最新的 MongoDB 版本中用作查询投影运算符。从 mongo 外壳:
db.parents.find(
{'children.age': {$gte: 18}},
{children:{$elemMatch:{age: {$gte: 18}}}})
This filters younger children's documents out of the childrenarray:
这将从children数组中过滤出年幼儿童的文档:
{ "_id" : ..., "children" : [ { "name" : "Margaret", "age" : 20 } ] }
{ "_id" : ..., "children" : [ { "name" : "John", "age" : 22 } ] }
As you can see, children are still grouped inside their parent documents. MongoDB queries return documents from collections. You can use the aggregation framework's $unwindmethod to split them into separate documents:
如您所见,子文档仍分组在其父文档中。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
}
I repeat the $matchclause for performance: the first time through it eliminates parents with nochildren at least 18 years old, so the $unwindonly considers useful documents. The second $matchremoves $unwindoutput that doesn't match, and the $projecthoists children's info from subdocuments to the top level.
我重复执行的$match条款:第一次通过它消除父母没有孩子至少18岁,所以$unwind只考虑有用的文件。第二个$match删除$unwind不匹配的输出,并将$project子文档中的子文档提升到顶级。
回答by AbdelHady
In Mongoose, you can also use the elegant .populate()function like this:
在 Mongoose 中,您还可以使用这样的优雅.populate()函数:
parents
.find({})
.populate({
path: 'children',
match: { age: { $gte: 18 }},
select: 'name age -_id'
})
.exec()
回答by cjwiseman11
A. Jesse Jiryu Davis's response works like a charm, however for later versions of Mongoose (Mongoose 5.x) we get the error:
A. Jesse Jiryu Davis 的回应很有魅力,但是对于更高版本的猫鼬(猫鼬 5.x),我们得到了错误:
Mongoose 5.x disallows passing a spread of operators to Model.aggregate(). Instead of Model.aggregate({ $match }, { $skip }), do Model.aggregate([{ $match }, { $skip }])
Mongoose 5.x 不允许将一系列运算符传递给Model.aggregate(). 而不是Model.aggregate({ $match }, { $skip }),做Model.aggregate([{ $match }, { $skip }])
So the code would simply now be:
所以代码现在就是:
> 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
}
(note the array brackets around the queries)
(注意查询周围的数组括号)
Hope this helps someone!
希望这可以帮助某人!

