Как вернуть большое количество строк из mongodb с помощью http-сервера node.js?

У меня есть пользовательская база данных в mongodb, которую я хотел бы экспортировать через интерфейс REST в JSON. Проблема в том, что в худшем случае количество возвращаемых строк превышает 2 миллиона.

Сначала я попробовал это

var mongo = require('mongodb'),
  Server = mongo.Server,
  Db = mongo.Db;
var server = new Server('localhost', 27017, {auto_reconnect: true});
var db = new Db('tracking', server);
var http = require('http');

http.createServer(function (request, response) {
  db.collection('users', function(err, collection) {
    collection.find({}, function(err, cursor){
      cursor.toArray(function(err, items) {
        output = '{"users" : ' + JSON.stringify(items) + '}';

        response.setHeader("Content-Type", "application/json");
        response.end(output);
      });
    });
  });
}).listen(8008);
console.log('Server running at localhost:8008');

, которое терпит неудачу при нехватке памяти. В примере используется драйвер node-mongodb-native и базовый пакет http.

FATAL ERROR: CALL_AND_RETRY_2 Выделение не выполнено — процессу не хватает памяти

(обратите внимание, что в реальном сценарии я использую параметры, которые ограничивают результаты по мере необходимости, но этот пример запрашивает их все, что независимо от худшего сценария)

Сами данные просты, например

{ "_id" : ObjectId("4f993d1c5656d3320851aadb"), "userid" : "80ec39f7-37e2-4b13-b442-6bea57472537", "user-agent" : "Mozilla/4.0 (совместимый ; MSIE 8.0; Windows NT 5.1; Trident/4.0; .NET CLR 1.1.4322)", "ip" : "127.0.0.1", "lastupdate": 1335442716 }

Я также пробовал что-то вроде

while(cursor != null)
{
  cursor.nextObject(function(err, item) {
    response.write(JSON.stringify(item));
  });
}

, но это тоже закончилась память.

Как мне поступить? Должен быть способ потоковой передачи данных построчно, но я не смог найти для него подходящий пример. О разбиении данных на страницы не может быть и речи из-за требований внешних приложений. Я думал записать данные в файл, а затем опубликовать его, но это приводит к нежелательным операциям ввода-вывода.

17
задан Community 22 September 2017 в 17:48
поделиться