Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/node.js/41.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何使用node.js http服务器从mongodb返回大量行?_Node.js_Mongodb_Rest_Http_Bigdata - Fatal编程技术网

如何使用node.js http服务器从mongodb返回大量行?

如何使用node.js http服务器从mongodb返回大量行?,node.js,mongodb,rest,http,bigdata,Node.js,Mongodb,Rest,Http,Bigdata,我在mongodb中有一个用户数据库,我想通过JSON中的REST接口导出它。问题是,在最坏的情况下,返回的行数远远超过200万 首先我试过这个 var mongo=require('mongodb'), Server=mongo.Server, Db=mongo.Db; var server=newserver('localhost',27017,{auto_reconnect:true}); var db=新数据库(“跟踪”,服务器); var http=require('http'); c

我在mongodb中有一个用户数据库,我想通过JSON中的REST接口导出它。问题是,在最坏的情况下,返回的行数远远超过200万

首先我试过这个

var mongo=require('mongodb'),
Server=mongo.Server,
Db=mongo.Db;
var server=newserver('localhost',27017,{auto_reconnect:true});
var db=新数据库(“跟踪”,服务器);
var http=require('http');
createServer(函数(请求、响应){
db.collection('users',函数(err,collection){
collection.find({},函数(err,游标){
cursor.toArray(函数(错误,项){
output='{“users”:'+JSON.stringify(items)+'}';
setHeader(“内容类型”、“应用程序/json”);
响应。结束(输出);
});
});
});
}).听(8008);
log('在本地主机上运行的服务器:8008');
内存不足时会失败。该示例使用节点mongodb本机驱动程序和基本http包

致命错误:调用和重试分配失败-进程内存不足

(请注意,在实际场景中,我使用的参数会根据需要限制结果,但本示例会查询所有这些参数,这是最坏的场景)

数据本身很简单,比如

{“用户id”:ObjectId(“4F993D1C56D3320851AADB”),“用户id”:“80ec39f7-37e2-4b13-b442-6BEA5742537”,“用户代理”:“Mozilla/4.0(兼容;MSIE 8.0;Windows NT 5.1;Trident/4.0;.NET CLR 1.1.4322)”,“ip:“127.0.0.1”,“最新更新”:1335442716}

我也试过类似的东西

while(光标!=null)
{
cursor.nextObject(函数(错误,项){
response.write(JSON.stringify(item));
});
}
但那也没什么记忆了


我应该如何进行?应该有一种方法来逐行传输数据,但我还没有找到合适的例子。由于外部应用程序的要求,分页数据是不可能的。我曾想过将数据写入一个文件,然后将其发布,但这会导致不需要的io。

好吧,我不再使用mongodb原生javascript驱动程序,但其中有相当好的streams实现

这两个驱动程序的语法非常相似。您可以使用猫鼬执行此操作:

response.setHeader("Content-Type", "application/json");
var stream = collection.find().stream();
stream.on('data', function(doc) {
   response.write(doc);  
});
stream.on('close', function() {
   response.end();
});

像这样的东西应该有用。如果没有,你可能应该在网站上打开一个问题


PS:它只是一个存根,我的意思是我不记得确切的语法,但它是您要查找的每个函数。

我发现node mongodb native Cursor对象对记录也有一个流选项(与
collection.find().streamRecords()
)即使在文档中没有提到它。请参阅和搜索“streamRecords”

最后,代码是这样结束的:

db.collection('users',函数(err,collection){
var first=真;
setHeader(“内容类型”、“应用程序/json”);
write(“{”用户“:[”);
var stream=collection.find().streamRecords();
stream.on('data',函数(项){
变量前缀=第一个?“”:‘,’;
write(前缀+JSON.stringify(item));
第一个=假;
});
stream.on('end',function(){
write(']}');
response.end();
});
});

本机
MongoDB
驱动程序的
游标.streamRecords()
方法已被弃用, 方法
stream()
更快


我已经解析了一个4000万行的acatalog文档,没有任何问题,使用
Mongodb
+
stream()
+
process.nextTick()

一个小模块使用Node的类来完成:


您可以更改
JSON.Stringify
部件,对来自mongodb游标的对象执行任何其他类型的“动态”转换,并节省一些内存。

实际上我也尝试过,但我原来问题中的
toArray
函数实际上包装/使用了
每个
函数,因此,当脚本内存不足时,它也失败了。是的,toArray需要缓冲整个数组,所以这没有帮助,但是cursor。你只需要用括号把它围起来。现在我又试了一次,它也能用了。由于某种原因,它以前失败了,我不得不回去检查我做错了什么。Mongoose将是解决数据存储问题的更好方法。您的回答让我在使用这个驱动程序时找到了正确的方向,我发现node mongodb native在游标中也有一个流选项,名为
streamResults
。稍后,我将仅使用节点mongodb本机发布有关我的问题的完整答案。感谢Timo分享您的解决方案!嘿@Timo,我们有没有办法从100000多个数据集中批量处理1000个流数据。我发现
cursor.stream()
的性能与
cursor.each()完全相同
。请确保为数千或数百万的批大小指定一个值rows@sha0Coder整个解析的时间量有多大?@sha0Coder您可以发布一些关于如何完成的要点吗?
http.createServer(function (request, response) {
  db.collection('users', function(err, collection) {
    collection.find({}, function(err, cursor){
      response.setHeader("Content-Type", "application/json");
      cursor.each(function(err, item) {
        if (item) {
          response.write(JSON.stringify(item));
        } else {
          response.end();
        }
      });
    });
  });
}).listen(8008);
var stream = require('stream');

function createCursorStream(){

    var cursorStream = new stream.Transform({objectMode:true});

    cursorStream._transform = function(chunk,encoding,done){
        if(cursorStream.started){
            cursorStream.push(', ' + JSON.stringify(chunk));
        }else{
            cursorStream.push('[' + JSON.stringify(chunk));
            cursorStream.started = true;
        }
        done();
    };

    cursorStream._flush = function(done){
        cursorStream.push(']');
        done();
    };

    return cursorStream;
}

module.exports.streamCursorToResponse = function(cursor,response){
    cursor.stream().pipe(createCursorStream()).pipe(response);
};