U kunt geen aggregation
gebruiken om een document bij te werken, maar u kunt het zeker gebruiken om de gegevens op te halen die u voor een update wilt gebruiken. Allereerst merkte ik dat er enkele {}
. zijn ontbreekt rond je grade
object binnen de grades
reeks. Misschien wilt u nogmaals controleren of uw documentstructuur is zoals gepost. Ten tweede zijn er een aantal problemen met uw aggregatiequery.
- De
$avg
operator werkt binnen een$group
clausule, geen$project
. - Als je
$avg
. gebruikt , u hoeft$sum
niet te gebruiken . - U wilt het gemiddelde van
trucks.grades.grade.grade_number
, die feitelijk de numerieke waarde van het cijfer bevat. Dat wil zeggen, je mistgrade
tussengrades
engrade_number
.
Als u deze problemen oplost, krijgt u een vraag die lijkt op het volgende:
db.col.aggregate([
{ "$unwind": "$trucks" },
{ "$unwind": "$trucks.grades" },
{ "$group":
{
"_id": "$trucks.truck_id",
"average_grade": { "$avg": "$trucks.grades.grade_number" }
}
}
]);
Voor uw voorbeelddocument geeft dat het volgende terug:
{ "_id" : "TEB5572", "average_grade" : 4 }
{ "_id" : "TEB7622", "average_grade" : 4 }
Nu kunt u deze informatie gebruiken om de average_grade
. bij te werken veld. Als u MongoDB versie 2.6 of hoger gebruikt, is de aggregate
methode zal een cursor teruggeven. U kunt door die cursor bladeren en de documenten dienovereenkomstig bijwerken.
In dit voorbeeld zoek ik naar documenten met een bepaalde truck_id
in hun trucks
array en ga verder met het bijwerken van de average_grade
met degene die is berekend door de aggregatiequery. U kunt het aanpassen aan uw behoeften. In combinatie met de aggregatiequery ziet de code er als volgt uit.
// 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});
}