Você não pode usar
aggregation
para atualizar um documento, mas você pode definitivamente usá-lo para obter os dados que deseja usar para uma atualização. Em primeiro lugar, notei que existem alguns {}
faltando na sua grade
objeto dentro das grades
variedade. Você pode querer verificar novamente se a estrutura do seu documento está conforme lançada. Em segundo lugar, há alguns problemas com sua consulta de agregação. - O
$avg
operador trabalha dentro de um$group
cláusula, não um$project
. - Quando você usa
$avg
, você não precisa usar$sum
. - Você deseja calcular a média de
trucks.grades.grade.grade_number
, que na verdade contém o valor numérico da nota. Ou seja, está faltandograde
entregrades
egrade_number
.
Se você resolver esses problemas, receberá uma consulta semelhante à seguinte:
db.col.aggregate([
{ "$unwind": "$trucks" },
{ "$unwind": "$trucks.grades" },
{ "$group":
{
"_id": "$trucks.truck_id",
"average_grade": { "$avg": "$trucks.grades.grade_number" }
}
}
]);
Para seu documento de amostra, isso retorna:
{ "_id" : "TEB5572", "average_grade" : 4 }
{ "_id" : "TEB7622", "average_grade" : 4 }
Agora você pode usar essas informações para atualizar o
average_grade
campo. Se você estiver usando o MongoDB versão 2.6 ou superior, o aggregate
O método retornará um cursor. Você pode percorrer esse cursor e atualizar os documentos de acordo. Neste exemplo, procuro documentos que tenham um determinado
truck_id
dentro de seus trucks
array e prossiga para atualizar o average_grade
com o calculado pela consulta de agregação. Você pode modificá-lo para atender às suas necessidades. Combinado com a consulta de agregação, o código se parece com isso. // 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});
}