2016-06-23 42 views
3

向超過1億個mongodb文檔添加新字段的最快和最安全的策略是什麼?在mongodb中爲1億條記錄添加新字段

背景

  • 在3節點複製品使用的mongodb 3.0設置

  • 我們當前文檔中添加了基於數據在另一個字段(post_time)一個新的字段(post_hour) 。 post_hour字段是post_time到小時的截斷版本。

回答

0

我遇到過類似的情況,並且創建了一個腳本來更新大約2500萬個文檔,並且需要大量時間來更新所有文檔。爲了提高性能,我逐一將更新後的文檔插入到一個新的集合中,並將其重新命名爲新集合。這種方法有助於我插入文檔而不是更新文檔(「插入」操作比「更新」操作快)。

下面是示例腳本(我沒有測試過):

/*This method returns postHour*/ 
function convertPostTimeToPostHour(postTime){ 
} 

var totalCount = db.person.count(); 
var chunkSize = 1000; 
var chunkCount = totalCount/chunkSize; 
offset = 0; 
for(index = 0; index<chunkCount; index++){ 
    personList = db.persons.find().skip(offset).limit(chunkSize); 
    personList.forEach(function (person) { 
     newPerson = person; 
     newPerson.post_hour = convertPostTimeToPostHour(person.post_time); 
     db.personsNew.insert(newPerson); // This will insert the record in a new collection 
    }); 
    offset += chunkSize; 
} 

當上面寫的腳本將得到執行,新的集合「personNew」將有更新的記錄與現場的價值「post_hour '集合。

如果現有集合具有任何索引,則需要在新集合中重新創建它們。

一旦創建了索引,就可以將集合'person'的名稱重命名爲'personOld'和'personNew'以'person'。

+0

我猜測在單獨的shell中執行每個塊都可以提高其速度性能。 –

-1

snapshot將允許以防止查詢結果的重複(如我們正在擴大規模) - 如果有任何問題發生,可以刪除。

請在下面找到其中「A1」是集名稱蒙戈shell腳本:

var documentLimit = 1000; 

var docCount = db.a1.find({ 
     post_hour : { 
      $exists : false 
     } 
    }).count(); 

var chunks = docCount/documentLimit; 

for (var i = 0; i <= chunks; i++) { 
    db.a1.find({ 
     post_hour : { 
      $exists : false 
     } 
    }).snapshot() 
     .limit(documentLimit) 
     .forEach(function (doc) { 
     doc.post_hour = 12; // put your transformation here 
     // db.a1.save(doc); // uncomment this line to save data 
          // you can also specify write concern here 
     printjson(doc);  // comment this line to avoid polution of shell output 
          // this is just for test purposes  
    }); 
} 

可以用參數玩,但大部分是在1000個記錄塊執行,看起來最佳。

相關問題