No puede usar aggregation
para actualizar un documento, pero definitivamente puede usarlo para obtener los datos que desea usar para una actualización. En primer lugar, noté que hay algunos {}
falta alrededor de su grade
objeto dentro de las grades
formación. Es posible que desee verificar que la estructura de su documento sea la publicada. En segundo lugar, hay un par de problemas con su consulta de agregación.
- El
$avg
el operador trabaja dentro de un$group
cláusula, no un$project
. - Cuando usas
$avg
, no necesita usar$sum
. - Desea promediar
trucks.grades.grade.grade_number
, que en realidad contiene el valor numérico de la calificación. Es decir, te faltagrade
entregrades
ygrade_number
.
Si resuelve esos problemas, obtendrá una consulta similar a la siguiente:
db.col.aggregate([
{ "$unwind": "$trucks" },
{ "$unwind": "$trucks.grades" },
{ "$group":
{
"_id": "$trucks.truck_id",
"average_grade": { "$avg": "$trucks.grades.grade_number" }
}
}
]);
Para su documento de muestra, eso devuelve:
{ "_id" : "TEB5572", "average_grade" : 4 }
{ "_id" : "TEB7622", "average_grade" : 4 }
Ahora puede usar esta información para actualizar la average_grade
campo. Si está utilizando MongoDB versión 2.6 o superior, el aggregate
método devolverá un cursor. Puede iterar a través de ese cursor y actualizar los documentos en consecuencia.
En este ejemplo, busco documentos que tengan un truck_id
particular. dentro de sus trucks
matriz y proceder a actualizar el average_grade
con el calculado por la consulta de agregación. Puedes modificarlo para adaptarlo a tus necesidades. Combinado con la consulta de agregación, el código se ve así.
// 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});
}