Как массово сохранить массив объектов в MongoDB?

#node.js #mongodb

#node.js #mongodb

Вопрос:

Я долго искал и не нашел ответа. Узел.В документах драйвера JS MongoDB говорится, что вы можете выполнять массовые вставки с помощью insert (docs), что хорошо и хорошо работает.

Теперь у меня есть коллекция с более чем 4 000 000 элементов, и мне нужно добавить новое поле ко всем из них. Обычно mongodb может записывать только 1 транзакцию за 100 мс, что означает, что я буду ждать несколько дней, чтобы обновить все эти элементы. Как я могу выполнить «массовое сохранение / обновление», чтобы обновить их все сразу? update () и save (), похоже, работают только с одним объектом.

псевдокод:

 var stuffToSave = [];
db.collection('blah').find({}, function(err, stuff) {
    stuff.toArray().forEach(function(item)) {
        item.newField = someComplexCalculationInvolvingALookup();
        stuffToSave.push(item);
    }
}
db.saveButNotSuperSlow(stuffToSave);
  

Конечно, мне нужно будет ограничить выполнение чего-то вроде 10 000 одновременно, чтобы не пытаться выполнять все 4 миллиона одновременно, но я думаю, вы поняли суть.

Комментарии:

1. Множество способов. Поделитесь некоторым кодом, даже плохим. Драйвер в последних версиях поддерживает массовые операции с обновлениями и другие операции. Ваша «статистика» также зависит от вашей собственной реализации. Не «жесткое» число, которое везде согласовано.

2. В первой части вы говорите о insert. Во второй части вы предполагаете, что вам нужно выполнить обновление, какое именно? вставить = новый документ, обновить = изменить существующий документ (ы)

3. Я просто указывал, что я хотел, чтобы та же функциональность предлагалась в insert, в API save(). Я обновлю его с помощью некоторого псевдокода.

4. Ваш комментарий на самом деле ничего не говорит, так что там не так много, чтобы понять неправильно. Вы понимаете амортизированные записи? Это то, что я имел в виду с моим «жестким числом». Что вы не понимаете в моем обновлении? Это не сложная задача: 1. запрос для всех объектов. 2. обновите новое поле для всех объектов. 3. сохраните все объекты. Я не могу опубликовать реальный код, потому что мой работодатель не позволит этого. Дело в том, что дайте мне знать, если вы до сих пор следите, insert() поддерживает передачу массива документов по какой-то причине. Есть ли эквивалент для save() ?

Ответ №1:

MongoDB позволяет обновлять множество документов, соответствующих определенному запросу, с помощью одного db.collection.update(query, update, options) вызова, см. Документацию. Например,

 db.blah.update(
   { },
   {
      $set: { newField: someComplexValue }
   },
   { 
      multi: true
   }
)
  

multi Опция позволяет команде обновлять все документы, соответствующие критериям запроса. Обратите внимание, что то же самое применяется при использовании узла.Драйвер JS, см. Эту документацию.

Если вы выполняете много разных обновлений для коллекции, вы можете обернуть их все в Bulk() конструктор, чтобы избежать некоторых накладных расходов на отправку нескольких обновлений в базу данных.