Du kan ikke bruge aggregation
at opdatere et dokument, men du kan helt sikkert bruge det til at få de data, du vil bruge til en opdatering. Først og fremmest har jeg bemærket, at der er nogle {}
mangler omkring din grade
objekt inde i grades
array. Du vil måske dobbelttjekke, at din dokumentstruktur er som den er bogført. For det andet er der et par problemer med din aggregeringsforespørgsel.
$avg
operatør arbejder i en$group
klausul, ikke et$project
.- Når du bruger
$avg
, behøver du ikke bruge$sum
. - Du vil have et gennemsnit af
trucks.grades.grade.grade_number
, som faktisk holder karakterens numeriske værdi. Det vil sige, du manglergrade
mellemgrades
oggrade_number
.
Hvis du løser disse problemer, får du en forespørgsel, der ligner følgende:
db.col.aggregate([
{ "$unwind": "$trucks" },
{ "$unwind": "$trucks.grades" },
{ "$group":
{
"_id": "$trucks.truck_id",
"average_grade": { "$avg": "$trucks.grades.grade_number" }
}
}
]);
For dit eksempeldokument returnerer det:
{ "_id" : "TEB5572", "average_grade" : 4 }
{ "_id" : "TEB7622", "average_grade" : 4 }
Nu kan du bruge disse oplysninger til at opdatere average_grade
Mark. Hvis du bruger MongoDB version 2.6 eller nyere, er aggregate
metoden returnerer en markør. Du kan iterere gennem markøren og opdatere dokumenterne i overensstemmelse hermed.
I dette eksempel søger jeg efter dokumenter, der har et bestemt truck_id
inde i deres trucks
array og fortsæt med at opdatere average_grade
med den, der er beregnet af aggregeringsforespørgslen. Du kan ændre det, så det passer til dine behov. Kombineret med aggregeringsforespørgslen ser koden sådan ud.
// 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});
}