将MongoDB结果流式传输到Express response



我正在尝试在没有第三方依赖项的情况下执行此操作,因为我认为不需要它们。请注意,由于架构师的裁决,我们必须使用MongoDB原生的,而不是Mongoose(不要问!)。

基本上我有一个getAll函数,它将从单个集合返回所有文档(基于传入的查询)。

文档的数量很容易达到几千个,因此,我想在收到它们时将它们流式传输出去。

我有以下代码:

db.collection('documents')
.find(query)
.stream({
transform: (result) => {
return JSON.stringify(new Document(result));
}
})
.pipe(res);

哪种工作,除了它破坏了文档应该所在的数组,并且它响应{...}{...}

一定有办法吧?

您可以做的是在请求数据库之前显式编写数组res.write("[")的开头,在每个 json 字符串化对象上放置一个,,并在流端写入数组的末尾res.write("]")这样就可以了。但这是不可取的!

JSON.stringify是一个非常缓慢的操作,您应该尽量少使用它。

更好的方法是使用可流式处理的JSON.stringify实现,例如json-stream-stringify

const JsonStreamStringify = require('json-stream-stringify');
app.get('/api/users', (req, res, next) => {
const stream = db.collection('documents').find().stream();
new JsonStreamStringify(stream).pipe(res);
);

请注意在生产中使用管道,管道在出错时不会破坏源或目标流。建议在生产中进行pumppipeline以避免内存泄漏。

最新更新