Не можете да използвате aggregation
за актуализиране на документ, но определено можете да го използвате, за да получите данните, които искате да използвате за актуализация. Първо, забелязах, че има някои {}
липсва около вашата grade
обект вътре в grades
масив. Може да искате да проверите отново дали структурата на вашия документ е както е публикувана. Второ, има няколко проблема с вашата заявка за обобщаване.
$avg
оператор работи вътре в$group
клауза, а не$project
.- Когато използвате
$avg
, не е необходимо да използвате$sum
. - Искате да осредните
trucks.grades.grade.grade_number
, което всъщност съдържа числовата стойност на оценката. Тоест, липсва виgrade
междуgrades
иgrade_number
.
Ако разрешите тези проблеми, ще получите заявка, подобна на следната:
db.col.aggregate([
{ "$unwind": "$trucks" },
{ "$unwind": "$trucks.grades" },
{ "$group":
{
"_id": "$trucks.truck_id",
"average_grade": { "$avg": "$trucks.grades.grade_number" }
}
}
]);
За вашия примерен документ, който връща:
{ "_id" : "TEB5572", "average_grade" : 4 }
{ "_id" : "TEB7622", "average_grade" : 4 }
Сега можете да използвате тази информация, за да актуализирате average_grade
поле. Ако използвате MongoDB версия 2.6 или по-нова, aggregate
метод ще върне курсор. Можете да преминете през този курсор и да актуализирате съответно документите.
В този пример търся документи, които имат определен truck_id
в техните trucks
масив и продължете да актуализирате average_grade
с тази, изчислена от заявката за агрегиране. Можете да го модифицирате, за да отговаря на вашите нужди. В комбинация със заявката за агрегиране, кодът изглежда така.
// Get average grade for each truck and assign results to cursor.
var cur = db.col.aggregate([
{ "$unwind": "$trucks" },
{ "$unwind": "$trucks.grades" },
{ "$group":
{
"_id": "$trucks.truck_id",
"average_grade": { "$avg": "$trucks.grades.grade_number" }
}
}
]);
// Iterate through results and update average grade for each truck.
while (cur.hasNext()) {
var doc = cur.next();
db.col.update({ "trucks.truck_id": doc._id },
{ "$set": { "trucks.$.average_grade": doc.average_grade }},
{ "multi": true});
}