繁体   English   中英

Stream 从 mongodb cursor 到 Z28A3689BE95C808DD5E7A37DB5Z16 中的表达响应

[英]Stream from a mongodb cursor to Express response in node.js

我正在玩弄所有花哨的 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()查询并返回 cursor

这会导致错误:

TypeError: first argument must be a string or Buffer

根据mongodb 驱动程序文档,我尝试将此转换器传递给stream()

function(obj) {return JSON.stringify(obj);}

但这无济于事。

谁能告诉我如何正确地 stream 做出回应?

还是唯一的解决方案是使用“数据”和“结束”事件手动抽取数据的样板?

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

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

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

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

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

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

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

您的mongo流正在将对象转储到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)

希望有所帮助

使用猫鼬并表达:

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();
    });
}

针对此问题的更好和最新的解决方案:

const { JsonStreamStringify } = require("json-stream-stringify");

app.get("/", (req, res) => {
  const cursor = db.collection("hello").find({}).limit(10).stream();
  x = new JsonStreamStringify(cursor).pipe(res);
  x.on("data", (doc) => {
    res.write(doc);
  });
});

上述解决方案是使用https://www.npmjs.com/package/json-stream-stringify package。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM