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.
$avg
operator bekerja di dalam$group
klausa, 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 kehilangangrade
antaragrade
dangrade_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});
}