#node.js #mongodb
#node.js #mongodb
Вопрос:
У меня есть приложение NodeJS, которое должно генерировать множество наборов данных синхронно (несколько вложенных циклов for). Предполагается, что эти наборы данных будут сохранены в моей базе данных MongoDB для более эффективного последующего поиска.
Я использую mongodb — драйвер для NodeJS и запускаю демон. Подключение к БД работает нормально, и, согласно окну демона, первая группа наборов данных успешно сохраняется. Каждые ~ 400-600 мс сохраняется другая группа, но после первого набора данных в консоли MongoDB больше нет выходных данных (даже ошибок), и поскольку размеры файлов не увеличиваются, я предполагаю, что эти операции записи не работают (я не могу дождаться их завершения, поскольку это займетнесколько дней до полного запуска).
Если я перезапущу скрипт NodeJS, он даже не сохранит первый ключ, возможно, из-за дубликатов? Если я удалю содержимое папки db, первое содержимое будет сохранено снова.
Это важная часть моего скрипта, и я не смог найти ничего, что я сделал неправильно. Я предполагаю, что проблема больше во внутренней логике (странные повторяющиеся проверки / не выполняется одновременно и т.д.).
var MongoClient = require('mongodb').MongoClient, dbBuffer = [];
MongoClient.connect('mongodb://127.0.0.1/loremipsum', function(err, db) {
if(err) return console.log("Cant connect to MongoDB");
var collection = db.collection('ipsum');
console.log("Connected to DB");
for(var q=startI;q<endI;q ) {
for(var w=0;w<words.length;w ) {
dbBuffer.push({a:a, b:b});
}
if(dbBuffer.length) {
console.log("saving " dbBuffer.length " items");
collection.insert(dbBuffer, {w:1}, function(err, result) {
if(err) {
console.log("Error on db write", err);
db.close();
process.exit();
}
});
}
dbBuffer = [];
}
db.close();
});
Обновить
- db.close никогда не вызывается, и соединение не прерывается
- Переход на массовую вставку ничего не меняет
- Обратный вызов для вставки никогда не вызывается — это может быть проблемой! Консоль MongoDB сообщает мне, что процесс вставки прошел успешно, но похоже, что связь между драйвером и MongoDB не работает должным образом для вставки.
Комментарии:
1.
collection.insert
это асинхронный вызов, поэтому ваш последнийdb.close()
вызов выполняется до их завершения.2. Кроме того, это хороший вариант использования для Bulk.insert (вместо взлома массива dbBuffer)
3. @JohnnyHK Как уже упоминалось, это упрощенный пример нескольких вложенных циклов, которые фактически выполняются несколько дней. Я вижу в консоли MongoDB, что соединение также не закрыто. Фелипе: Вы правы, и я попробую, но на самом деле это не должно быть большой разницей.
4. Теперь изменил код и запустил его на другой машине, та же проблема.
Ответ №1:
Я «решил» это сам. Одно из моих заблуждений заключалось в том, что каждая транзакция вставки подтверждается в консоли MongoDB, в то время как на самом деле она подтверждает только первую или если между командами проходит некоторое время. Чтобы проверить, действительно ли процесс вставки работает, нужно некоторое время запускать скрипт и ждать, пока MongoDB загрузит его в локальный файл (примерно 30-60 секунд).
Кроме того, процессы вставки были слишком быстрыми друг за другом, и MongoDB, похоже, неправильно обрабатывает это в Win10 x64. Я перешел из буфера массива во внутренний буфер (см. Комментарии) и продолжил процесс только после вставки предыдущих данных.
Это упрощенный результирующий код
db.collection('seedlist', function(err, collection) {
syncLoop(0,0, collection);
//...
});
function syncLoop(q, w, collection) {
batch = collection.initializeUnorderedBulkOp({useLegacyOps: true});
for(var e=0;e<words.length;e ) {
batch.insert({a:a, b:b});
}
batch.execute(function(err, result) {
if(err) throw err;
//...
return setTimeout(function() {
syncLoop(qNew,wNew,collection);
}, 0); // Timer to prevent Memory leak
});
}