Děláte to správným způsobem, ale nezahrnuli jste prvek pole, který by se měl shodovat, do části dotazu .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)
}
}
);
}
})
Musíte tedy porovnat něco v poli, aby poziční $
operátora.
Mohli jste také použít hodnotu "index" v zápisu, protože to stejně vytváříte ve smyčce:
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
);
}
})
Který používá pouze odpovídající index a je užitečný tam, kde neexistuje žádný jedinečný identifikátor prvku pole.
Všimněte si také, že by zde neměly platit ani možnosti „upsert“ ani „multi“ vzhledem k povaze toho, jak toto zpracovává existující dokumenty.
Jako "postscriptovou" poznámku k tomu je také vhodné zvážit Bulk Operations API MongoDB ve verzích od 2.6 a vyšších. Pomocí těchto metod API můžete výrazně snížit objem síťového provozu mezi klientskou aplikací a databází. Zjevné zlepšení je zde v celkové rychlosti:
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();
To v podstatě snižuje množství příkazů operací odeslaných na server na odesílání pouze jednou za 1000 operací ve frontě. Můžete si hrát s tímto číslem a tím, jak jsou věci seskupeny, ale relativně bezpečným způsobem to výrazně zvýší rychlost.