Está haciendo esto de la manera correcta, pero no incluyó el elemento de matriz para que coincida en la parte de consulta 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)
}
}
);
}
})
Por lo tanto, debe hacer coincidir algo en la matriz para que el posicional $
operador tenga algún efecto.
También podría haber usado el valor "índice" en la notación, ya que de todos modos lo está produciendo en un bucle:
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
);
}
})
Que solo usa el índice coincidente y es útil cuando no hay un identificador único del elemento de la matriz.
También tenga en cuenta que ni las opciones "upsert" ni "multi" deben aplicarse aquí debido a la naturaleza de cómo se procesan los documentos existentes.
Solo como una nota de "posdata" a esto, también vale la pena considerar la API de operaciones masivas de MongoDB en versiones de 2.6 y posteriores. Con estos métodos API, puede reducir significativamente la cantidad de tráfico de red entre su aplicación cliente y la base de datos. La mejora obvia aquí está en la velocidad general:
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();
Básicamente, esto reduce la cantidad de declaraciones de operaciones enviadas al servidor a solo enviar una vez cada 1000 operaciones en cola. Puedes jugar con ese número y cómo se agrupan las cosas, pero te dará un aumento significativo en la velocidad de una manera relativamente segura.