Правите това по правилния начин, но не сте включили елемента на масива за съвпадение в частта за заявка на .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)
}
}
);
}
})
Така че трябва да съпоставите нещо в масива, за да може позиционният $
оператор, за да има ефект.
Можете също така просто да използвате стойността "индекс" в нотацията, тъй като така или иначе създавате това в цикъл:
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
);
}
})
Което просто използва съответстващия индекс и е удобно, когато няма уникален идентификатор на елемента на масива.
Също така имайте предвид, че нито опциите „upsert“, нито „multi“ трябва да се прилагат тук поради естеството на начина, по който се обработват съществуващи документи.
Само като бележка за "постскриптум" към това, също така си струва да разгледате API за групови операции на MongoDB във версии от 2.6 и по-нови. С помощта на тези API методи можете значително да намалите количеството мрежов трафик между вашето клиентско приложение и базата данни. Очевидното подобрение тук е в общата скорост:
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();
Това основно намалява количеството операции, изпратени до сървъра, до изпращане само веднъж на всеки 1000 операции на опашка. Можете да играете с това число и как са групирани нещата, но това ще даде значително увеличение на скоростта по относително безопасен начин.