sql >> Databasteknik >  >> NoSQL >> MongoDB

Hur ändrar man datatyp för kapslat fält i Mongo-dokument?

Du gör detta på rätt sätt men du inkluderade inte arrayelementet för att matcha i frågedelen av .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)
             }
         }
      );
  }
})

Så du måste matcha något i arrayen för att positionella $ operatören att ha någon effekt.

Du kunde också bara ha använt "index"-värdet i notationen, eftersom du ändå producerar det i en loop:

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

Som bara använder det matchande indexet och är praktiskt där det inte finns någon unik identifierare för arrayelementet.

Observera också att varken alternativen "upsert" eller "multi" bör gälla här på grund av hur detta behandlar befintliga dokument.

Precis som en "efterskrift"-notering till detta är det också värt att överväga Bulk Operations API för MongoDB i versioner från 2.6 och senare. Genom att använda dessa API-metoder kan du avsevärt minska mängden nätverkstrafik mellan din klientapplikation och databasen. Den uppenbara förbättringen här är den totala hastigheten:

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

Detta minskar i princip mängden operationsuttalanden som skickas till servern till att bara skickas en gång var 1000:e köade operation. Du kan spela med det numret och hur saker är grupperade men det kommer att ge en avsevärd ökning av hastigheten på ett relativt säkert sätt.



  1. Är det säkert att ta bort journalfilen för mongodb?

  2. Mongoose - find():objekt i sökalternativen fungerar inte

  3. Openshift NodeJS + MongoDB-applikationen stannar plötsligt

  4. CRUD nodejs/expressserver:app.put req.body är tom