Anda tidak dapat menggunakan aggregation untuk memperbarui dokumen, tetapi Anda pasti dapat menggunakannya untuk mendapatkan data yang ingin Anda gunakan untuk pembaruan. Pertama-tama, saya perhatikan ada beberapa {} hilang di sekitar grade . Anda objek di dalam grade Himpunan. Anda mungkin ingin memeriksa ulang apakah struktur dokumen Anda sudah seperti yang diposting. Kedua, ada beberapa masalah dengan kueri agregasi Anda.
$avgoperator bekerja di dalam$groupklausa, bukan$project.- Saat Anda menggunakan
$avg, Anda tidak perlu menggunakan$sum. - Anda ingin rata-rata
trucks.grades.grade.grade_number, yang sebenarnya menyimpan nilai numerik kelas. Artinya, Anda kehilangangradeantaragradedangrade_number.
Jika Anda menyelesaikan masalah tersebut, Anda mendapatkan kueri yang mirip dengan berikut ini:
db.col.aggregate([
{ "$unwind": "$trucks" },
{ "$unwind": "$trucks.grades" },
{ "$group":
{
"_id": "$trucks.truck_id",
"average_grade": { "$avg": "$trucks.grades.grade_number" }
}
}
]);
Untuk dokumen sampel Anda, yang mengembalikan:
{ "_id" : "TEB5572", "average_grade" : 4 }
{ "_id" : "TEB7622", "average_grade" : 4 }
Sekarang Anda dapat menggunakan informasi ini untuk memperbarui average_grade bidang. Jika Anda menggunakan MongoDB versi 2.6 atau lebih tinggi, aggregate metode akan mengembalikan kursor. Anda dapat mengulangi kursor tersebut dan memperbarui dokumen yang sesuai.
Dalam contoh ini, saya mencari dokumen yang memiliki truck_id tertentu di dalam trucks . mereka array dan lanjutkan untuk memperbarui average_grade dengan yang dihitung oleh kueri agregasi. Anda dapat memodifikasinya sesuai dengan kebutuhan Anda. Dikombinasikan dengan kueri agregasi, kodenya terlihat seperti ini.
// 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});
}