如何使用内存数据库传输响应?
我正在使用Loki JS作为内存数据库。有一个特殊的资源,我必须返回一个表的整个内容(不能被分页),并且该表可以增长到500,000项左右,大约300mb。
在其他情况下,我使用fs.createReadStream来获取文件并将其流回给用户:
fs.createReadStream('zips.json')
.on('data', function() {
res.write(...)
})
.on('end', function() {
res.end();
})
这对大文件很有用,但是如何使用内存数据库做一些相同的事情呢?
const items = lokiDb.addCollection('items');
items.insert('a bunch of items ...');
// I would now like to stream items via res.write
res.write(items)
目前,res.write(items)
会导致内存问题,因为Node尝试立即返回整个响应。
答案 0 :(得分:0)
据我所知,Loki没有本地流提供商,但我可能错过了它。您可能想要做的是听取'插入'集合上的事件并写下,如下:
const items = lokiDb.addCollection('items');
items.on('insert', (results) => {
res.write(results);
});
items.insert('a bunch of items ...');
答案 1 :(得分:0)
如果我是正确的,基本上你的问题是readStreams只读取文件,并且你想从内存数据结构中读取。解决方案可能是定义自己的readStream类,稍微修改原型stream.Readable._read方法:
var util = require('util');
var stream = require('stream');
"use strict";
var begin=0, end=0;
var options = {
highWaterMark: 16384,
encoding: null,
objectMode: false
};
util.inherits(InMemoryStream, stream.Readable);
function InMemoryStream(userDefinedOptions, resource){
if (userDefinedOptions){
for (var key in userDefinedOptions){
options.key = userDefinedOptions[key];
}
}
this.resource = resource;
stream.Readable.call(this, options);
}
InMemoryStream.prototype._read = function(size){
end += size;
this.push(this.resource.slice(begin, end));
begin += size;
}
exports.InMemoryStream = InMemoryStream;
exports.readStream = function(UserDefinedOptions, resource){
return new InMemoryStream(UserDefinedOptions, resource);
}
您将内存中的数据结构(在下面的示例中为数组)转换为readStream,并将其传递给writeStream,如下所示:
"use strict";
var fs = require('fs');
var InMemoryStream = require('/home/regular/javascript/poc/inmemorystream.js');
var stored=[], writestream, config={};
config = {
encoding: null,
fileToRead: 'raphael.js',
fileToWrite: 'secondraphael.js'
}
fs.readFile(config.fileToRead, function(err, data){
if (err) return console.log('Error when opening file', err);
stored = data;
var inMemoryStream = InMemoryStream.readStream({encoding: config.encoding}, stored);
writestream = fs.createWriteStream(config.fileToWrite);
inMemoryStream.pipe(writestream);
inMemoryStream.on('error', function(err){
console.log('in memory stream error', err);
});
});