0

我有一个包含以下文档的集合:

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

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

4

1 回答 1

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
}
于 2015-10-07T11:24:32.193 回答