MongoDB docs $ group

时间:2015-12-09 01:42:23

标签: mongodb aggregation-framework database

我在MongoDB中有一个文档:

student{
    id: ...id
    name: ...
    student:[{ 
        group_number: ...
        results:[{subj: ... , mark: 5},{...},{...}]
    }]

}

我需要使用

db.student.aggregate({$group: {_id : "$_id", 
                               mark_total : {$sum : $student.results.mark}}                

})

问题是$ student.results.mark返回undefined,因此聚合返回

"result":[
    {
    "_id" : 2,
    "mark_total: : 0
    }
 ],
"ok" : 1

as $ sum什么都不返回

你有什么建议?

1 个答案:

答案 0 :(得分:2)

student.results是一个数组,使用$student.results.mark访问它时不返回任何内容,用于嵌入文档的访问字段。 您需要首先使用$unwind stage

使元素的每个元素成为嵌入元素

示例数据

db.student.insert([{
    name: 'Foo',
    student:[{ 
        group_number: 1,
        results:[{subj: 'Math', mark: 5}, {subj: 'Info', mark: 4}, {subj: 'English', mark: 3}]
    }]
 }])

最终查询

db.student.aggregate([
    { "$unwind": "$student" },
    { "$unwind": "$student.results" },
    { "$group": { _id: "$_id", mark_total: { $sum: "$student.results.mark" } } }
]);

最终输出

{ "_id" : ObjectId("566790f6e1f3a57c81bdf2f9"), "mark_total" : 12 }

由于student字段是一个数组,第一阶段{ "$unwind": "$student" }将使{ group_number: 1, results:[{subj: 'Math', mark: 5}, {subj: 'Info', mark: 4}, {subj: 'English', mark: 3}]}成为嵌入文档。 第一个$unwind阶段后的输出

{ "_id" : ObjectId("566790f6e1f3a57c81bdf2f9"), "name" : "Foo", "student" : { "group_number" : 1, "results" : [ { "subj" : "Math", "mark" : 5 }, { "subj" : "Info", "mark" : 4 }, { "subj" : "English", "mark" : 3 } ] } }

然后你需要再次放松,因为" $ student.results"仍然是一个数组 第二次放松后的输出

{ "_id" : ObjectId("566790f6e1f3a57c81bdf2f9"), "name" : "Foo", "student" : { "group_number" : 1, "results" : { "subj" : "Math", "mark" : 5 } } }
{ "_id" : ObjectId("566790f6e1f3a57c81bdf2f9"), "name" : "Foo", "student" : { "group_number" : 1, "results" : { "subj" : "Info", "mark" : 4 } } }
{ "_id" : ObjectId("566790f6e1f3a57c81bdf2f9"), "name" : "Foo", "student" : { "group_number" : 1, "results" : { "subj" : "English", "mark" : 3 } } }

您现在可以使用" $ student.results.mark"

访问该标记