2016-06-23 2 views
3

Какова самая быстрая и безопасная стратегия для добавления нового поля в более чем 100 миллионов документов mongodb?Добавление нового поля в 100 миллионов записей в mongodb

фон

  • Использование MongoDB 3.0 в реплике 3 узла установлен

  • Мы добавляем новое поле (post_hour), который основан на данных в другом поле (post_time) в текущем документе , Поле post_hour представляет собой усеченную версию post_time до часа.

ответ

0

Я столкнулся с похожим сценарием и в котором я создал сценарий для обновления около 25 миллионов документов, и для обновления всех документов потребовалось много времени. Чтобы повысить производительность, я один за другим вставил обновленный документ в новую коллекцию и переименовал новую коллекцию. Этот подход помог, потому что я вставлял документы, а не обновлял их (операция «вставки» выполняется быстрее, чем операция «обновление»).

Вот пример сценарий (я не проверял):

/*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 ' задавать.

Если у существующей коллекции есть какие-либо индексы, вам необходимо воссоздать их в новой коллекции.

После этого индексы создаются, вы можете переименовать имя коллекции «человек» в «personOld» и «personNew» на «person».

+0

Я уверен, что выполнение каждого фрагмента в отдельной оболочке также может повысить скорость работы. –

-1

snapshot позволит предотвратить дубликаты в результате запроса (как мы расширяем размер) - может быть удален, если какие-либо проблемы случаются.

Пожалуйста найти Монго скрипт ниже, где «a1» это название коллекции:

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 записей блоков, что выглядит оптимальным.

Смежные вопросы