MongoDB-使用查询提取嵌入文档
我收集了以下文件:MongoDB-使用查询提取嵌入文档,mongodb,embedded-documents,Mongodb,Embedded Documents,我收集了以下文件: { name: "Johann", surname: "Esburg", jobs: [ { "profession": "chef", "salary": 1000 }, { "profession": "gardener", "salary": 800 } ] }, { name: "Sam",
{
name: "Johann",
surname: "Esburg",
jobs: [
{
"profession": "chef",
"salary": 1000
}, {
"profession": "gardener",
"salary": 800
}
]
},
{
name: "Sam",
surname: "Sonite",
jobs: [
{
"profession": "doctor",
"salary": 2000
}, {
"profession": "barber",
"salary": 850
}
]
}
我希望找到所有薪水超过900英镑的工作,因此结果将是:
[
{
"profession": "chef",
"salary": 1000
}, {
"profession": "doctor",
"salary": 2000
}
]
我很确定我必须求助于mongodb聚合。我所取得的最好成绩是:
db.persons.aggregate([
{$unwind: "$jobs"},
{$match: {"jobs.salary": {$gt: 900}}},
{$project: {jobs: 1, _id: 0}}])
这将返回:
[
{
"jobs": {
"profession": "chef",
"salary": 1000
}
},
{
"jobs": {
"profession": "doctor",
"salary": 2000
}
}
]
但这不是我想要的。我还希望删除作业密钥。
我知道一种可能性是在投影中指定嵌入文档的每个变量,如下所示:
db.persons.aggregate([
{$unwind: "$jobs"},
{$match: {"jobs.salary": {$gt: 900}}},
{$project:
{"profession": "$jobs.profession",
"salary": "$jobs.salary", _id: 0}}])
但是我更愿意避免它,因为嵌入的文档可能在某些字段上有所不同。考虑以下聚合管道操作,管道作为第一步是确保高效操作所必需的,因为聚合可以使用索引以及查询集合,以尽量减少进入管道的文档数量:
db.persons.aggregate([
{
"$match": {
"jobs.salary": { "$gt": 900 }
}
},
{
"$unwind": "$jobs"
},
{
"$match": {
"jobs.salary": { "$gt": 900 }
}
},
{
"$group": {
"_id": null,
"jobs": {
"$push": {
"profession": "$jobs.profession",
"salary": "$jobs.salary"
}
}
}
},
{
"$unwind": "$jobs"
},
{
"$project": {
"_id": 0, "profession": "$jobs.profession", "salary": "$jobs.salary"
}
}
])
样本输出:
group by{U id:null如下{$unwind:$jobs},{$match:{jobs.salary:{$gt:900}},{$group:{U id:null,results:{$push:$jobs}}@Yogesh这是我想要的一个很好的近似值。谢谢结果是正确的,但它相当于我在问题中提出的第二个解决方案。问题是我会避免显式指定结果的每个字段,这是您在group语句中所做的。@tano上面的结果与您在问题中指定的预期结果相同,我看不出这与不需要的第二个解决方案有什么相似之处。问题不是结果。事实上,我在问题中使用的对象只是一个示例。我的真实对象更复杂,它们可以随着时间的推移而变化,其中一些对象可能缺少一些字段。因此,很难像在组和项目报表中那样逐个指定字段。
/* 0 */
{
"result" : [
{
"profession" : "chef",
"salary" : 1000
},
{
"profession" : "doctor",
"salary" : 2000
}
],
"ok" : 1
}