2015-12-09 3 views
0

У меня есть документ в 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 вернуть ничего

Что вы посоветуете?

ответ

2

Вы student.results - это массив, доступ к нему с помощью $student.results.mark не возвращает ничего, что используется для поля доступа встроенного документа. Вам нужно будет сделать каждый элемент элемента, чтобы стать внедренный элемент первым с $unwind стадии

Выборочные данные

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» по-прежнему является массивом выход после 2 размотки

{ "_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 "

+0

спасибо, это очень помогло! Но что делать, если у меня будет сотни предметов, поэтому после разматывания моего документа весит более 16 МБ, а mongoDB вернет ошибку, превышающую максимальный размер. Что мне делать? Использовать API GridFS? – Arganzas

+0

Я думаю, что вы что-то совершили, раскрутите сцену, разбив большой документ на несколько меньших, поэтому размер каждого маленького документа намного меньше, чем у большого. Кроме того, на этапе обработки документы могут превышать лимит 16mb (https://docs.mongodb.org/manual/core/aggregation-pipeline-limits/) – somallg

Смежные вопросы