Mam bazy danych użytkowników w mongodb, które chciałbym eksportować za pośrednictwem interfejsu REST w JSON. Problem polega na tym, że w najgorszym przypadku ilość zwróconych wierszy wynosi znacznie ponad 2 miliony.Jak zwrócić dużą liczbę wierszy z mongodb przy użyciu serwera http node.js?
Najpierw próbowałem to
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');
który zawodzi, gdy zabraknie pamięci. W przykładzie użyto sterownika macierzystego node-mongodb i podstawowego pakietu http.
FATAL ERROR: CALL_AND_RETRY_2 Allocation failed - process out of memory
(zauważ, że w realnym scenariuszu I wykorzystać parametry, które ograniczają wyniki, ile potrzeba, ale ten przykład odpytuje je wszystko co jest najgorszym przypadku niezależnie)
Sam danych jest proste, jak
{ "_id" : ObjectId("4f993d1c5656d3320851aadb"), "userid" : "80ec39f7-37e2-4b13-b442-6bea57472537", "user-agent" : "Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 5.1; Trident/4.0; .NET CLR 1.1.4322)", "ip" : "127.0.0.1", "lastupdate" : 1335442716 }
próbowałem też coś
while(cursor != null)
{
cursor.nextObject(function(err, item) {
response.write(JSON.stringify(item));
});
}
ale zabrakło także pamięć.
Jak powinienem kontynuować? Powinien istnieć sposób przesyłania danych wiersz po wierszu, ale nie byłem w stanie znaleźć odpowiedniego dla niego przykładu. Przesyłanie stron danych nie wchodzi w grę z powodu zewnętrznych wymagań aplikacji. Pomyślałem o zapisaniu danych do pliku, a następnie opublikowaniu go, ale to prowadzi do niechcianego io.
Zauważyłem, że 'cursor.stream()' wykonuje dokładnie to samo, co 'cursor.each()'. – Meekohi
Pamiętaj, aby podać wartość dla 'batchSize' dla tysięcy lub milionów wierszy – alexishacks
Czy możesz wkleić swój pełny kod tutaj – parkerproject