Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/node.js/39.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

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/mongodb/11.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
来自mongodb游标的流,用于在node.js中表示响应_Node.js_Mongodb_Express - Fatal编程技术网

来自mongodb游标的流,用于在node.js中表示响应

来自mongodb游标的流,用于在node.js中表示响应,node.js,mongodb,express,Node.js,Mongodb,Express,我正在玩弄所有花哨的node.js/mongodb/express平台,偶然发现了一个问题: app.get('/tag/:tag', function(req, res){ var tag=req.params.tag; console.log('got tag ' + tag + '.'); catalog.byTag(tag,function(err,cursor) { if(err) { console.dir(err); res.end

我正在玩弄所有花哨的node.js/mongodb/express平台,偶然发现了一个问题:

app.get('/tag/:tag', function(req, res){
  var tag=req.params.tag;
  console.log('got tag ' + tag + '.');
  catalog.byTag(tag,function(err,cursor) {
     if(err) {
       console.dir(err);
       res.end(err);
     } else {
       res.writeHead(200, { 'Content-Type': 'application/json'});

       //this crashes
       cursor.stream().pipe(res);

     }
  });
});
正如您可能猜到的,
catalog.byTag(tag,callback)
对Mongodb执行
find()
查询并返回光标

这将导致一个错误:

TypeError: first argument must be a string or Buffer
根据,, 我试图将此转换器传递到
流()

但这没有帮助

有谁能告诉我如何正确地流式处理响应


或者,唯一的解决方案是使用“数据”和“结束”事件手动泵送数据的样板文件吗?

您的mongo流正在将对象转储到res流中,而res流只能处理字符串或缓冲区(因此出现错误)

幸运的是,流很容易通过管道连接在一起,所以制作转换流来字符串化数据并不太难

在节点v0.10.21中:

var util = require('util')
var stream = require('stream')
var Transform = stream.Transform

util.inherits(Stringer, Transform)

function Stringer() {
  Transform.call(this, { objectMode: true } )
  // 'object mode allows us to consume one object at a time

}

Stringer.prototype._transform = function(chunk, encoding, cb) {
  var pretty = JSON.stringify(chunk, null, 2) 
  this.push(pretty) // 'push' method sends data down the pike.
  cb() // callback tells the incoming stream we're done processing 
}

var ss = new Stringer()

db.createObjectStreamSomehow()
  .pipe(ss)
  .pipe(res)

希望这有助于

将光标流与结合使用,将其输送到响应对象

cursor.stream().pipe(JSONStream.stringify()).pipe(res);

简单
.stream({transform:JSON.stringify})

function(req, res){
    var stream = database.tracks.find({}).stream();
    stream.on('data', function (doc) {
        res.write(JSON.stringify(doc));
    });
    stream.on('end', function() {
        res.end();
    });
}

这里是其他答案的有效组合

app.get('/comments', (req, res) => {
  Comment.find()
    .cursor()
    .pipe(JSONStream.stringify())
    .pipe(res.type('json'))
})

  • cursor()
    返回一个与节点streams3兼容的流,它比不推荐使用的
    query.stream()接口更可取
  • 通过管道连接到
    JSONStream.stringify()
    ,将文档合并到一个数组中,而不是单个对象
  • 管道到
    res.type('json')
    ,它将HTTP
    内容类型
    头设置为
    应用程序/json
    ,并再次返回自身(响应流)

如果将catalog.byTag替换为对MongoDB本机驱动程序的直接调用,是否有效?否,相同的错误。另外,我可以调用
toArray()
并通过
res.json()
发送,这是可行的,但我更喜欢流式传输,而不是在服务器上缓冲并在之后发送(并且确保您在之前
res.set('Content-Type','application/json');
,否则您的响应将被解释为文本)不过,这不会生成有效的JSON,它只是将字符串化的对象连接在一起,而不是将其正确地包装在数组中。@robertklep你说得对!我不知道。谢谢因为我们正在处理express,所以这里似乎需要一些错误处理。我想看看一些推荐的模式。@robertklep对于有效的JSON输出,有什么替代方案?@Tiago当前的答案将起作用(我的评论提到了答案的早期版本,该版本已被编辑和修复)。
app.get('/comments', (req, res) => {
  Comment.find()
    .cursor()
    .pipe(JSONStream.stringify())
    .pipe(res.type('json'))
})