Anda melakukan ini dengan cara yang benar tetapi Anda tidak menyertakan elemen larik untuk dicocokkan dengan bagian kueri .update()
:
db.collectionName.find({
"topProcesses":{"$exists":true}}).forEach(function(data){
for(var ii=0;ii<data.topProcesses.length;ii++) {
db.collectionName.update(
{
"_id": data._id,
"topProcesses.processId": data.topProcesses[ii].processId // corrected
},
{
"$set": {
"topProcesses.$.cpuUtilizationPercent":
parseFloat(data.topProcesses[ii].cpuUtilizationPercent)
}
}
);
}
})
Jadi, Anda perlu mencocokkan sesuatu dalam larik agar kode
Anda juga bisa saja menggunakan nilai "indeks" dalam notasi, karena Anda tetap memproduksinya dalam satu lingkaran:
db.collectionName.find({
"topProcesses":{"$exists":true}}).forEach(function(data){
for(var ii=0;ii<data.topProcesses.length;ii++) {
var updoc = {
"$set": {}
};
var myKey = "topProcesses." + ii + ".cpuUtilizationPercent";
updoc["$set"][myKey] = parseFloat(data.topProcesses[ii].cpuUtilizationPercent);
db.collectionName.update(
{
"_id": data._id
},
updoc
);
}
})
Yang hanya menggunakan indeks yang cocok dan berguna di mana tidak ada pengidentifikasi unik dari elemen array.
Perhatikan juga bahwa opsi "upsert" atau "multi" tidak boleh diterapkan di sini karena sifatnya yang memproses dokumen yang ada.
Sama seperti catatan "postscript" untuk ini, juga bermanfaat untuk mempertimbangkan API Operasi Massal MongoDB dalam versi dari 2.6 dan yang lebih baru. Dengan menggunakan metode API ini, Anda dapat secara signifikan mengurangi jumlah lalu lintas jaringan antara aplikasi klien dan database. Peningkatan yang jelas di sini adalah dalam kecepatan keseluruhan:
var bulk = db.collectionName.initializeOrderedBulkOp();
var counter = 0;
db.collectionName.find({
"topProcesses":{"$exists":true}}
).forEach(function(data){
for(var ii=0;ii<data.topProcesses.length;ii++) {
var updoc = {
"$set": {}
};
var myKey = "topProcesses." + ii + ".cpuUtilizationPercent";
updoc["$set"][myKey] = parseFloat(data.topProcesses[ii].cpuUtilizationPercent);
// queue the update
bulk.find({ "_id": data._id }).update(updoc);
counter++;
// Drain and re-initialize every 1000 update statements
if ( counter % 1000 == 0 ) {
bulk.execute();
bulk = db.collectionName.initializeOrderedBulkOp();
}
}
})
// Add the rest in the queue
if ( counter % 1000 != 0 )
bulk.execute();
Ini pada dasarnya mengurangi jumlah pernyataan operasi yang dikirim ke server menjadi hanya mengirim sekali setiap 1000 operasi yang antri. Anda dapat bermain dengan nomor itu dan bagaimana hal-hal dikelompokkan, tetapi itu akan memberikan peningkatan kecepatan yang signifikan dengan cara yang relatif aman.