2015-10-07 57 views
0

提取嵌入文档我有一个集合中包含的文件如下:MongoDB的 - 与查询

{ 
    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 aggregation。我设法做到的最好的是:

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 
     } 
    } 
] 

但这不是我想要的。我还希望jobs密钥被删除。 我知道有一个可能性是指定在projection这样嵌入文档的每个变量:

db.persons.aggregate([ 
    {$unwind: "$jobs"}, 
    {$match: {"jobs.salary": {$gt: 900}}}, 
    {$project: 
     {"profession": "$jobs.profession", 
     "salary": "$jobs.salary", _id: 0}}]) 

但我宁愿避免它,因为嵌入文档可以在某些领域有所不同。

+1

组由'_id:像这样的'null' { “$开卷”: “$工作”},{“$匹配“:{”jobs.salary“:{$ gt:900}},{”$ group“:{”_ id“:null,”results“:{”$ push“:”$ jobs“}}}' – Yogesh

+0

@Yogesh这是我想要的一个很好的近似值。谢谢 – tano

回答

0

考虑以下聚集流水线运作,$match管道作为第一个步骤是必要的,以确保高效的操作聚集可以使用索引以及查询集合应当尽量减少进入管道的文档数:

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" 
     } 
    } 
]) 

样本输出:

/* 0 */ 
{ 
    "result" : [ 
     { 
      "profession" : "chef", 
      "salary" : 1000 
     }, 
     { 
      "profession" : "doctor", 
      "salary" : 2000 
     } 
    ], 
    "ok" : 1 
} 
+0

结果是正确的,但它相当于我在我的问题中暴露的第二个解决方案。问题是我会避免明确指定每个结果字段,这就是你在'group'语句中所做的。 – tano

+0

@tano上面的结果等同于您在问题中指定的预期结果,但我未能看出它与不希望的第二种解决方案的相似程度。 – chridam

+0

问题不在于结果。事实是,我在问题中使用的对象仅仅是一个例子。我的真实对象更复杂,它们可以随时间变化,其中一些可能会丢失一些字段。因此,像在“组”和“项目”语句中一样指定字段是不方便的。 – tano