Sie können aggregation
nicht verwenden um ein Dokument zu aktualisieren, aber Sie können es definitiv verwenden, um die Daten zu erhalten, die Sie für ein Update verwenden möchten. Als erstes ist mir aufgefallen, dass es einige {}
gibt fehlt um Ihre grade
Objekt innerhalb der grades
Reihe. Möglicherweise möchten Sie noch einmal überprüfen, ob Ihre Dokumentstruktur wie gebucht ist. Zweitens gibt es einige Probleme mit Ihrer Aggregationsabfrage.
- Der
$avg
-Operator arbeitet innerhalb einer$group
-Klausel, kein$project
. - Wenn Sie
$avg
verwenden , müssen Sie$sum
nicht verwenden . - Sie möchten
trucks.grades.grade.grade_number
mitteln , die eigentlich den numerischen Wert der Note enthält. Das heißt, Ihnen fehltgrade
zwischengrades
undgrade_number
.
Wenn Sie diese Probleme beheben, erhalten Sie eine Abfrage ähnlich der folgenden:
db.col.aggregate([
{ "$unwind": "$trucks" },
{ "$unwind": "$trucks.grades" },
{ "$group":
{
"_id": "$trucks.truck_id",
"average_grade": { "$avg": "$trucks.grades.grade_number" }
}
}
]);
Für Ihr Beispieldokument gibt das zurück:
{ "_id" : "TEB5572", "average_grade" : 4 }
{ "_id" : "TEB7622", "average_grade" : 4 }
Jetzt können Sie diese Informationen verwenden, um average_grade
zu aktualisieren aufstellen. Wenn Sie MongoDB Version 2.6 oder höher verwenden, wird die Datei aggregate
Methode gibt einen Cursor zurück. Sie können diesen Cursor durchlaufen und die Dokumente entsprechend aktualisieren.
In diesem Beispiel suche ich nach Dokumenten, die eine bestimmte truck_id
haben in ihren trucks
-Array und fahren Sie mit der Aktualisierung von average_grade
fort mit der von der Aggregationsabfrage berechneten. Sie können es an Ihre Bedürfnisse anpassen. Kombiniert mit der Aggregationsabfrage sieht der Code so aus.
// 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});
}