MongoDB
 sql >> Database >  >> NoSQL >> MongoDB

Come modificare il tipo di dati del campo nidificato nel documento Mongo?

Lo stai facendo nel modo giusto ma non hai incluso l'elemento dell'array da abbinare nella parte della query di .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)
             }
         }
      );
  }
})

Quindi è necessario abbinare qualcosa nell'array in modo che posizionale $ operatore per avere alcun effetto.

Avresti anche potuto semplicemente usare il valore "index" nella notazione, dal momento che lo stai comunque producendo in un ciclo:

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
      );
  }
})

Che utilizza solo l'indice di corrispondenza ed è utile dove non esiste un identificatore univoco dell'elemento dell'array.

Tieni inoltre presente che in questo caso non dovrebbero essere applicate né le opzioni "upsert" né "multi", a causa della natura del modo in cui vengono elaborati i documenti esistenti.

Proprio come una nota "postscript" a questo, vale anche la pena considerare l'API Bulk Operations di MongoDB nelle versioni dalla 2.6 in poi. Utilizzando questi metodi API è possibile ridurre significativamente la quantità di traffico di rete tra l'applicazione client e il database. L'evidente miglioramento qui è nella velocità complessiva:

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();

Ciò riduce sostanzialmente la quantità di istruzioni delle operazioni inviate al server per l'invio solo una volta ogni 1000 operazioni in coda. Puoi giocare con quel numero e come sono raggruppate le cose, ma darà un aumento significativo della velocità in un modo relativamente sicuro.