从mongodb游标流到node.js中的Express响应

h0r*_*ru5 19 mongodb node.js 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(err);
     } else {
       res.writeHead(200, { 'Content-Type': 'application/json'});

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

     }
  });
});
Run Code Online (Sandbox Code Playgroud)

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

这会导致错误:

TypeError: first argument must be a string or Buffer
Run Code Online (Sandbox Code Playgroud)

根据mongodb驱动程序doc,我试图将此转换器传递给stream():

function(obj) {return JSON.stringify(obj);}
Run Code Online (Sandbox Code Playgroud)

但这没有用.

任何人都可以告诉我如何正确地将某些内容传递给响应吗?

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

rob*_*lep 20

结合使用游标流JSONStream将其传递给响应对象.

cursor.stream().pipe(JSONStream.stringify()).pipe(res);
Run Code Online (Sandbox Code Playgroud)

  • (并确保你`res.set('Content-Type','application/json');`之前,因为你的反应将被解释为文本.) (5认同)

小智 8

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


ssh*_*how 8

这里有其他答案的工作组合

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

http://mongoosejs.com/docs/api.html#query_Query-cursor

  • cursor()返回与Nodestream3兼容的流,并且优先于已弃用的query.stream()接口.
  • 管道以JSONStream.stringify()将文档组合成数组而不是单个对象
  • res.type('json')用于设置HTTP Content-Type标头的管道application/json并再次返回自身(响应流).

  • @Tiago 当前的答案将起作用(我的评论指的是该答案的先前版本,该版本已被编辑和修复)。 (2认同)