2016-12-16 62 views
0

我正在使用express.js服务器。我试图用猫鼬使用对象的数组(每个对象都有_id属性和它的值对应于每个文档_id使用数组对象更新多个文档

一种方法是通过数组循环并执行MongoDB的集合在更新现有文件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)); 
    }); 
} 

但是这种方式我将不得不处理异步场景,并且必须检查所有迭代的数据库查询何时完成,然后只将响应从服务器发送回客户端。

猫鼬内部是否有任何其他方法可以一次编辑/修改对象数组,然后调用回调函数?

注* - 每个数组对象都有_id存在,它与文档_id的值匹配。

回答

0

是的,这很可能。您可以利用批量写入API来处理异步操作,从而提高性能,尤其是处理大型数据集。对于支持MongoDB Server 3.2.x, 的Mongoose版本>=4.3.0,您可以使用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); 

对于猫鼬版本~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

警告:每次启动所有元素并行。

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