UI允许用户选择几个查询参数并通过AJAX提交。 服务器将使用参数查询mongoDB,并在服务器上创建一个非常大的CSV文件(30列/ 1.5MM行/ ~1GB)。 创建文件后,服务器将使用URL响应AJAX调用以下载文件。 第二次调用服务器以下载CSV文件。
我的问题是扩展此解决方案...当尝试从mongoDB检索超过50,0000条记录时,Node.js内存不足。系统运行时带有4GB内存。
AJAX调用创建和下载文件:
handleExport: function (){
NProgress.done();
NProgress.start();
var data = {spMle: this.state.spMle, custMle: this.state.custMle};
$.ajax({
type: 'POST',
url: '/api/aps/export',
data: data,
success: function (filename){
NProgress.done();
var url = '/api/aps/export/download/' + filename
$('body').append("<iframe src='" + url + "' style='display: none;' ></iframe>");
//window.open(url);
}
});
},
服务器请求从MongoDB查询创建CSV文件,并发送URL以将文件下载回客户端:
var spMle = req.body.spMle;
var custMle = req.body.custMle;
var limit = 50000;
var filename = 'export.csv';
var path = './public/downloads/' + filename;
var query = ApsModel.find();
if (spMle !== "0"){query.where('SP_MLE_ID').equals(spMle);}
if (custMle !== "0"){query.where('Cust_MLE_ID').equals(custMle);}
if (limit){query.limit(limit);}
var writeStream = fs.createWriteStream(path);
writeStream.on('finish', function () {
console.log('CSV file completed!');
res.send(filename);
});
var readStream = query.stream({ transform: JSON.stringify});
var json2CsvStream = new Json2CsvStream();
json2CsvStream.on('header', function(data) {
// console.log(' ++ yeah header found ++');
// return console.log(data);
})
json2CsvStream.on('line', function(data) {
console.log('row streamed');
// return console.log(data);
});
readStream.pipe(json2CsvStream).pipe(writeStream);
下载文件的服务器请求:
router.get('/aps/export/download/:filename', function (req, res){
var path = './public/downloads/' + req.params.filename;
res.download(path, "export.csv")
});
答案 0 :(得分:3)
使用端到端的流将其重构为以下数据流:
1)管道mongo查询 2)将数据传输到json-to-csv解析器 3)将解析后的数据传输到客户端
Jquery电话:
handleExport: function (){
var url ="/api/aps/export/" + this.state.spMle + "/" + this.state.custMle;
$('body').append("<iframe src='" + url + "' style='display: none;' ></iframe>");
//window.open(url);
},
服务器响应:
/* GET aps export */
router.get('/aps/export/:spMle/:custMle', function (req, res){
var spMle = req.params.spMle;
var custMle = req.params.custMle;
var limit = 250000;
var filename = 'export.csv';
var query = ApsModel.find();
if (spMle !== "0"){query.where('SP_MLE_ID').equals(spMle);}
if (custMle !== "0"){query.where('Cust_MLE_ID').equals(custMle);}
if (limit){query.limit(limit);}
var headers = {
'Content-Type': 'text/csv',
'Content-disposition': 'attachment;filename=' + filename
}
res.writeHead(200, headers)
var mongoStream = query.stream({transform: JSON.stringify});
var parser = new Json2CsvStream();
//run streams
mongoStream.pipe(parser).pipe(res)
});