Transmitir desde un cursor mongodb a la respuesta Express en node.js

Estoy jugando con todas las elegantes plataformas node.js / mongodb / express, y tropecé con un problema:

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

Como probablemente haya adivinado, catalog.byTag(tag, callback) hace una consulta find() a Mongodb y devuelve el cursor

Esto conduce a un error:

 TypeError: first argument must be a string or Buffer 

De acuerdo con el controlador mongodb doc , traté de pasar este convertidor a stream() :

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

pero eso no ayuda.

¿Alguien puede decirme cómo transmitir correctamente algo a una respuesta?

¿O la única solución es un estándar para bombear manualmente los datos usando los eventos ‘datos’ y ‘final’?

Una combinación funcional de otras respuestas aquí

 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() devuelve una secuencia compatible Node streams3 y es preferible a la interfaz de query.stream() desuso.
  • JSONStream.stringify() a JSONStream.stringify() para combinar documentos en una matriz en lugar de objetos individuales
  • Piping to res.type('json') que establece el Content-Type HTTP Content-Type en application/json y se devuelve a sí mismo (el flujo de respuesta) nuevamente.

Use la secuencia de cursor en combinación con JSONStream para canalizarlo a su objeto de respuesta.

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

Sencillo. .stream({transform: JSON.stringify});

Su secuencia mongo está volcando objetos en la stream de res que solo puede manejar cadenas o búferes (de ahí el error).

Afortunadamente, las transmisiones son fáciles de conectar juntas, por lo que no es demasiado difícil realizar una transmisión de transformación para codificar sus datos.

en el nodo 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) 

Espero que ayude

Usando mongoose y expreso:

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