Je doet dit op de juiste manier, maar je hebt het array-element dat moet overeenkomen niet opgenomen in het querygedeelte van de .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)
}
}
);
}
})
U moet dus iets in de array matchen om de positionele $
operator om enig effect te hebben.
Je had ook gewoon de "index"-waarde in de notatie kunnen gebruiken, aangezien je die hoe dan ook in een lus produceert:
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
);
}
})
Die alleen de overeenkomende index gebruikt en handig is als er geen unieke identificatie van het array-element is.
Houd er ook rekening mee dat noch de "upsert"- of "multi"-opties hier van toepassing zouden moeten zijn vanwege de aard van de manier waarop bestaande documenten worden verwerkt.
Net als een "postscript" opmerking hierbij, is het ook de moeite waard om de Bulk Operations API van MongoDB in versies vanaf 2.6 en hoger te overwegen. Met behulp van deze API-methoden kunt u de hoeveelheid netwerkverkeer tussen uw clienttoepassing en de database aanzienlijk verminderen. De duidelijke verbetering hier zit in de algehele snelheid:
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();
Dit vermindert in feite het aantal bewerkingsinstructies dat naar de server wordt verzonden tot slechts één keer per 1000 bewerkingen in de wachtrij. Je kunt met dat nummer spelen en hoe dingen zijn gegroepeerd, maar het zal op een relatief veilige manier een aanzienlijke snelheidsverhoging geven.