Vous ne pouvez pas utiliser l'aggregation
pour mettre à jour un document, mais vous pouvez certainement l'utiliser pour obtenir les données que vous souhaitez utiliser pour une mise à jour. Tout d'abord, j'ai remarqué qu'il y a des {}
manquant autour de votre grade
objet à l'intérieur des grades
déployer. Vous voudrez peut-être vérifier que la structure de votre document est telle que publiée. Deuxièmement, il y a quelques problèmes avec votre requête d'agrégation.
- Le
$avg
l'opérateur travaille à l'intérieur d'un$group
clause, pas un$project
. - Lorsque vous utilisez
$avg
, vous n'avez pas besoin d'utiliser$sum
. - Vous voulez faire la moyenne de
trucks.grades.grade.grade_number
, qui contient en fait la valeur numérique de la note. C'est-à-dire qu'il vous manquegrade
entregrades
etgrade_number
.
Si vous résolvez ces problèmes, vous obtenez une requête semblable à la suivante :
db.col.aggregate([
{ "$unwind": "$trucks" },
{ "$unwind": "$trucks.grades" },
{ "$group":
{
"_id": "$trucks.truck_id",
"average_grade": { "$avg": "$trucks.grades.grade_number" }
}
}
]);
Pour votre exemple de document, cela renvoie :
{ "_id" : "TEB5572", "average_grade" : 4 }
{ "_id" : "TEB7622", "average_grade" : 4 }
Vous pouvez maintenant utiliser ces informations pour mettre à jour le average_grade
champ. Si vous utilisez MongoDB version 2.6 ou supérieure, le aggregate
méthode renverra un curseur. Vous pouvez parcourir ce curseur et mettre à jour les documents en conséquence.
Dans cet exemple, je recherche des documents qui ont un truck_id
particulier à l'intérieur de leurs trucks
tableau et procéder à la mise à jour du average_grade
avec celui calculé par la requête d'agrégation. Vous pouvez le modifier selon vos besoins. Combiné avec la requête d'agrégation, le code ressemble à ceci.
// 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});
}