我曾经使用过 mongodb,但对 mongoose ORM 还很陌生。我试图从集合中获取数据,explain() 输出显示 50 毫秒。通过 mongoose 获取数据的总时间为 9 秒。这是查询:
Node.find({'dataset': datasetRef}, function (err, nodes){
// handle error and data here
});
然后我在我查询的字段上应用了索引。 explain() 输出现在显示 4ms。但通过 mongoose 检索数据的总时间没有改变。然后我搜索了一下,发现使用lean()可以帮助使mongoose中的读取查询性能非常接近原生mongodb
所以我将查询更改为:
Node.find({'dataset': datasetRef})
.lean()
.stream({transform: JSON.stringify})
.pipe(res)
这彻底解决了性能问题。但最终结果是一个 JSON 文档流,如下所示:
{var11: val11, var12: val12}{var21: val21, var22: val22} ...
我如何解析它以形成文档数组?或者我根本不应该使用流?在我看来,如果我计划在后端形成数组,那么使用流是没有意义的,因为我将不得不等待所有文档读入内存。但我也认为在前端解析和创建整个数组可能会很昂贵。
在这种情况下如何才能获得最佳性能而不堵塞网络?
UPDATE
我正在尝试使用直通流来解决这个问题。但是,我还无法在 JSON 对象之间插入逗号。请参阅下面的代码:
res.write("[");
var through = require('through');
var tr = through(
function write(data){
this.queue(data.replace(/\}\{/g,"},{"));
}
);
var dbStream = db.node.find({'dataset': dataSetRef})
.lean()
.stream({'transform': JSON.stringify});
dbStream.on("end", function(){
res.write("]");
});
dbStream
.pipe(tr)
.pipe(res);
这样,我就可以在开头得到“[”,在结尾得到“]”。但是,仍然无法将patten“}{”替换为“},{”。不确定我做错了什么
UPDATE 2
现在弄清楚为什么替换不起作用。看起来,由于我已将转换函数指定为 JSON.stringify,因此它一次读取一个 JSON 对象,因此永远不会遇到该模式}{
因为它永远不会一次选择多个 JSON 元素。
现在我修改了代码,并编写了一个自定义转换函数,该函数执行 JSON.stringify,然后在末尾附加一个逗号。我在这里面临的唯一问题是我不知道它什么时候是流中的最后一个 JSON 对象。因为我不想在这种情况下添加逗号。目前,一旦遇到结尾,我就会追加一个空的 JSON 对象。但不知怎的,这看起来并不是一个令人信服的想法。这是代码:
res.write("[");
function transform(data){
return JSON.stringify(data) + ",";
}
var dbStream = db.node.find({'dataset': dataSetRef})
.lean()
.stream({'transform': transform});
dbStream.on("end", function(){
res.write("{}]");
});
dbStream
.pipe(res);