0

多個文檔,我有一些40000條記錄,我需要更新planId字段和記錄複製到同一個集合。 現在我使用的基本MongoDB的複製和更新在同一個集合

linkModel.find({},callback) & linkModel.insertMany([linksArray],callback) 

但它佔用了大量的時間。 我已經試過了,但聚集,而我想更新它不能代替$out運營商替換現有的集合。

到目前爲止,我已經嘗試了三個步驟:

db.links.aggregate([ { $match: { planId: ObjectId("5732f50a6886e5421259e823") } }, { $out: "temp" } ]);

db.temp.updateMany({planId:ObjectId("5732f50a6886e5421259e823")},{$set:{planId:ObjectId("5791b25f203b5e92316e60c3")}})

db.temp.copyTo("links")

但即使CopyTo方法將是緩慢的。 對此有更快的方法嗎?使用Bulk API散裝做更新的

回答

0

利用。他們提供更好的性能,你會說1000,你不是每次發送請求給服務器,這是更爲有效的批次中每1000個請求被髮送操作的服務器,但只有一次。

下面演示了這種方法,第一個例子使用MongoDB中的版本>= 2.6 and < 3.2提供的大宗原料藥。它由所有Cost領域不斷變化的浮動值字段更新集合中的所有 文件:

var bulk = db.links.initializeUnorderedBulkOp(), 
    counter = 0; 

db.links.find({ planId: ObjectId("5732f50a6886e5421259e823") }) 
     .snapshot().forEach(function (doc) {   
    bulk.find({ "_id": doc._id }).updateOne({ 
     "$set": { "planId": ObjectId("5791b25f203b5e92316e60c3") } 
    }); 

    counter++; 
    if (counter % 1000 == 0) { 
     bulk.execute(); // Execute per 1000 operations 
     // re-initialize every 1000 update statements 
     bulk = db.links.initializeUnorderedBulkOp(); 
    } 
}) 
// Clean up remaining operations in queue 
if (counter % 1000 != 0) { bulk.execute(); } 

下一個例子適用於新的MongoDB 3.2版具有自deprecatedBulk API和提供較新的一套使用bulkWrite()的API。

它使用與上述相同的遊標,但使用相同的forEach()遊標方法創建帶批量操作的陣列,以將每個批量寫入文檔推送到數組。因爲寫命令可以接受不超過1000點的操作,你需要將你的操作有最多1000的操作和重新intialise數組時,循環打1000迭代:

var cursor = db.links.find({ planId: ObjectId("5732f50a6886e5421259e823") }).snapshot(), 
    bulkUpdateOps = []; 

cursor.forEach(function(doc){   
    bulkUpdateOps.push({ 
     "updateOne": { 
      "filter": { "_id": doc._id }, 
      "update": { "$set": { "planId": ObjectId("5791b25f203b5e92316e60c3") } } 
     } 
    }); 

    if (bulkUpdateOps.length == 1000) { 
     db.links.bulkWrite(bulkUpdateOps); 
     bulkUpdateOps = []; 
    } 
});   

if (bulkUpdateOps.length > 0) { db.links.bulkWrite(bulkUpdateOps); }