簡體   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