Non puoi usare aggregation
per aggiornare un documento, ma puoi sicuramente usarlo per ottenere i dati che desideri utilizzare per un aggiornamento. Prima di tutto, ho notato che ci sono alcuni {}
manca intorno al tuo grade
oggetto all'interno dei grades
Vettore. Potresti voler ricontrollare che la struttura del tuo documento sia come pubblicata. In secondo luogo, ci sono un paio di problemi con la tua query di aggregazione.
- Il
$avg
l'operatore lavora all'interno di un$group
clausola, non un$project
. - Quando usi
$avg
, non è necessario utilizzare$sum
. - Vuoi fare una media di
trucks.grades.grade.grade_number
, che contiene effettivamente il valore numerico del voto. Cioè, ti manca ilgrade
tragrades
egrade_number
.
Se risolvi questi problemi, ricevi una query simile alla seguente:
db.col.aggregate([
{ "$unwind": "$trucks" },
{ "$unwind": "$trucks.grades" },
{ "$group":
{
"_id": "$trucks.truck_id",
"average_grade": { "$avg": "$trucks.grades.grade_number" }
}
}
]);
Per il tuo documento di esempio, che restituisce:
{ "_id" : "TEB5572", "average_grade" : 4 }
{ "_id" : "TEB7622", "average_grade" : 4 }
Ora puoi utilizzare queste informazioni per aggiornare il average_grade
campo. Se stai utilizzando MongoDB versione 2.6 o successiva, aggregate
il metodo restituirà un cursore. Puoi scorrere il cursore e aggiornare i documenti di conseguenza.
In questo esempio, cerco documenti che hanno un particolare truck_id
all'interno dei loro trucks
array e procedi con l'aggiornamento di average_grade
con quello calcolato dalla query di aggregazione. Puoi modificarlo in base alle tue esigenze. In combinazione con la query di aggregazione, il codice è simile a questo.
// 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});
}