2016-12-16 4 views
0

Ich benutze express.js Server. Ich versuche, bestehende Dokumente in mongodb Sammlung zu aktualisieren Mungo mit mit Array von Objekten (jedes Objekt _id Eigenschaft und deren Wert entspricht jedem Dokument _id.)Aktualisieren mehrerer Dokumente mit Array von Objekt

Ein Ansatz Schleife durch Array ist, und führen Sie findByIdAndUpdate()

for(var i=0; i < expenseListToEdit.length; i++) {  
    var expense = expenseListToEdit[i]; 

    Expense.findByIdAndUpdate(expense._id, expense, function(err, model) { 
     if (err) {  
      console.log('Error occurred while editing expense'); 
     } 

     console.log('model: ' + util.inspect(model)); 
    }); 
} 

Aber auf diese Weise muss ich asynchrone Szenario behandeln und müssen überprüfen, wenn db-Abfrage für alle Iteration beendet ist dann nur senden Antwort zurück zum Client vom Server.

Gibt es einen alternativen Ansatz innerhalb von Mungo, um Array von Objekten auf einmal zu bearbeiten/ändern und dann den Callback aufzurufen?

Hinweis * - Jedes Array-Objekt verfügt über _id vorhanden, die mit Dokument _id Wert übereinstimmt.

Antwort

0

Ja, das ist durchaus möglich. Sie könnten die Bulk-Schreib-API für die Verarbeitung der asynchronen Operationen und damit für eine bessere Leistung nutzen, insbesondere bei großen Datenmengen. Für Mongoose-Versionen >=4.3.0, die MongoDB Server 3.2.x, unterstützen, können Sie bulkWrite() für Updates verwenden. Das folgende Beispiel zeigt, wie Sie vorgehen können:

var bulkUpdateCallback = function(err, r){ 
    console.log(r.matchedCount); 
    console.log(r.modifiedCount); 
} 
// Initialise the bulk operations array 
var bulkOps = expenseListToEdit.map(function (expense) { 
    return { 
     "updateOne": { 
      "filter": { "_id": expense._id } ,    
      "update": { "$set": expense } 
     }   
    }  
}); 

// Get the underlying collection via the native node.js driver collection object 
Expense.collection.bulkWrite(bulkOps, { "ordered": true, w: 1 }, bulkUpdateCallback); 

Für Mongoose Versionen ~3.8.8, ~3.8.22, 4.x die Unterstützung MongoDB Server >=2.6.x Sie Bulk API wie folgt

var bulk = Expense.collection.initializeOrderedBulkOp(), 
    counter = 0; 

expenseListToEdit.forEach(function(expense) { 
    bulk.find({ "_id": expense._id }) 
     .updateOne({ "$set": expense }); 

    counter++; 
    if (counter % 500 == 0) { 
     bulk.execute(function(err, r) { 
      // do something with the result 
      bulk = Expense.collection.initializeOrderedBulkOp(); 
      counter = 0; 
     }); 
    } 
}); 

// Catch any docs in the queue under or over the 500's 
if (counter > 0) { 
    bulk.execute(function(err, result) { 
     // do something with the result here 
    }); 
} 
0

Die Lösung ist verwenden könnte die for zu ändern Aussage von async.eachhttp://caolan.github.io/async/docs.html#each:

Warnung: Die einzelnen starten alle Elemente s parallel.

async.each(expenseListToEdit, function (expense, done) { 
    Expense.findByIdAndUpdate(expense._id, expense, function(err, model) { 
     if (err) {  
      console.log('Error occurred while editing expense'); 
      done(err); // if an error occured, all each is stoped 
      return; 
     } 

     console.log('model: ' + util.inspect(model)); 
     done(); 
    }); 
}, function (err) { 
    // final callback launched after all findByIdAndUpdate calls. 
}); 
0
for (let i of expenseListToEdit) { 
    Expense.findByIdAndUpdate(i._id, {}) 
    .exec() 
    .then(function updated(expense) { 
     if (expense) { 
      //DO SMTH 
     } 
     }).then(null, function(err) { 
      console.error(err) 
      throw err; 
     }) 
} 
+0

bitte versuchen Sie es eine Erklärung hinzuzufügen, wie dieser Code funktioniert und warum, vielleicht mit Links zur Dokumentation – dhdavvie

Verwandte Themen