向超過1億個mongodb文檔添加新字段的最快和最安全的策略是什麼?在mongodb中爲1億條記錄添加新字段
背景
在3節點複製品使用的mongodb 3.0設置
我們當前文檔中添加了基於數據在另一個字段(post_time)一個新的字段(post_hour) 。 post_hour字段是post_time到小時的截斷版本。
向超過1億個mongodb文檔添加新字段的最快和最安全的策略是什麼?在mongodb中爲1億條記錄添加新字段
背景
在3節點複製品使用的mongodb 3.0設置
我們當前文檔中添加了基於數據在另一個字段(post_time)一個新的字段(post_hour) 。 post_hour字段是post_time到小時的截斷版本。
我遇到過類似的情況,並且創建了一個腳本來更新大約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'。
的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個記錄塊執行,看起來最佳。
我猜測在單獨的shell中執行每個塊都可以提高其速度性能。 –