Поток из курсора mongodb в экспресс-ответ в 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)
выполняет запрос find()
к Mongodb и возвращает курсор
Это приводит к ошибке:
TypeError: first argument must be a string or Buffer
В соответствии с doc mongodb,
Я попытался передать этот преобразователь в stream()
:
function(obj) {return JSON.stringify(obj);}
но это не помогает.
Может ли кто-нибудь сказать мне, как правильно передать что-то в ответ?
Или это единственное решение, позволяющее вручную накачивать данные с помощью событий "данных" и "конца"?
Ответы
Ответ 1
Рабочая комбинация других ответов здесь
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()
возвращает поток, совместимый с потоками Node streams3, и является предпочтительным по сравнению с устаревшим интерфейсом query.stream()
.
- Подключение к
JSONStream.stringify()
для объединения документов в массив вместо отдельных объектов
- Настроить на
res.type('json')
, который устанавливает заголовок HTTP Content-Type
в application/json
и снова возвращает себя (поток ответов).
Ответ 2
Используйте поток курсора в сочетании с JSONStream
, чтобы передать его в ваш объект ответа.
cursor.stream().pipe(JSONStream.stringify()).pipe(res);
Ответ 3
Simple. .stream({transform: JSON.stringify});
Ответ 4
Ваш поток mongo сбрасывает объекты в поток res, который может обрабатывать только строки или буферы (следовательно, ошибка).
К счастью, потоки легко соединяются друг с другом, поэтому не слишком сложно сделать поток преобразования, чтобы укрепить ваши данные.
в node 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)
надеюсь, что поможет
Ответ 5
Использование мангуста и выражения:
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();
});
}