2016-12-16 4 views
0

Я использую сервер express.js. Я пытаюсь обновить существующие документы в коллекции MongoDB использование мангуста с массивом объектов (каждый объект имеет _id свойство и его значение соответствует каждому документу _id.)Обновление нескольких документов с использованием массива объекта

Один подхода перебрать массив и выполнить 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)); 
    }); 
} 

Но таким образом мне придется обрабатывать асинхронный сценарий и вам придется проверять, когда db-запрос для завершения итерации завершен, а затем отправлять ответ обратно клиенту с сервера.

Есть ли альтернативный подход в мангусте для редактирования/изменения массива объекта за один раз, а затем вызова обратного вызова?

Примечание * - Каждый объект массива имеет _id, который соответствует документу _id значение.

ответ

0

Да, это вполне возможно. Вы могли бы воспользоваться преимуществами API для массовой загрузки для обработки асинхронных операций и, следовательно, повышения производительности, особенно для больших наборов данных. Для версий Mongoose >=4.3.0, которые поддерживают MongoDB Server 3.2.x, вы можете использовать bulkWrite() для уточнений. Следующий пример показывает, как вы можете об этом:

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

Для Mongoose версий ~3.8.8, ~3.8.22, 4.x, которые поддерживают MongoDB сервер >=2.6.x, вы могли бы использовать Bulk API следующим

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

решение изменить for заявление от async.eachhttp://caolan.github.io/async/docs.html#each:

Предупреждение: каждый запуск всего элемента s параллельно.

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

пожалуйста, попробуйте добавить некоторые пояснения относительно того, как работает этот код и почему, может быть, со ссылками на документацию – dhdavvie