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

Hvordan ændres datatype af indlejret felt i Mongo-dokument?

Du gør dette på den rigtige måde, men du inkluderede ikke array-elementet til at matche i forespørgselsdelen af ​​.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 skal matche noget i arrayet for at positionelle $ operatør for at have nogen virkning.

Du kunne også bare have brugt "indeks"-værdien i notationen, da du alligevel producerer 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 blot bruger det matchende indeks og er praktisk, hvor der ikke er en unik identifikator for array-elementet.

Bemærk også, at hverken "upsert" eller "multi"-mulighederne bør gælde her på grund af arten af, hvordan dette behandler eksisterende dokumenter.

Ligesom en "efterskrift" note til dette, er det også værd at overveje Bulk Operations API fra MongoDB i versioner fra 2.6 og nyere. Ved at bruge disse API-metoder kan du betydeligt reducere mængden af ​​netværkstrafik mellem din klientapplikation og databasen. Den åbenlyse forbedring her er i den samlede hastighed:

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

Dette reducerer dybest set mængden af ​​operationserklæringer, der sendes til serveren, til kun at sende én gang for hver 1000 handlinger i kø. Du kan lege med det tal, og hvordan tingene er grupperet, men det vil give en betydelig stigning i hastigheden på en relativt sikker måde.



  1. Tilgange til lagring af geospatiale data i Redis

  2. Hvordan opdaterer jeg kun MongoDB-dokumentfelter, hvis de ikke eksisterer?

  3. Sådan udelukker du nogle felter fra dokumentet

  4. Forespørg et indlejret array i MongoDb