【发布时间】:2018-11-29 12:22:35
【问题描述】:
我是 node.js 生态系统的新手,需要一些帮助。
我有当用户调用 URL 时触发的控制器。
async function get_all_information(req, res, next) {
try {
let start_date = req.query.start_date;
let end_date = req.query.end_date;
const binds = {};
binds.start_date = start_date;
binds.end_date = end_date;
let query = `SOME LONG SQL STATEMENT`;
await pool.query(query, binds, function (error, results) {
if (error) throw error;
console.log(results); // ~ 10 seconds
res.send(JSON.stringify(results)); // ~ 15 seconds
});
} catch (error) {
next(error);
}
}
我尝试使用此代码,但遇到了问题。返回数据库的每月数据池有227011 rows。似乎stringify 方法创建了太大的 JSON 文件。当我尝试测试时,Postman 应用程序崩溃了。我试图分析并注意到每天的数据池会创建约 13 MB 的 JSON 文件。我们可以说每月数据池可以创建约 400 MB 的 JSON 文件。
然后我尝试像这样流式传输查询行:
pool.query('HUGE SQL QUERY').stream({ highWaterMark: 5 }).pipe(res);
不幸的是这样的代码引发错误:
TypeError [ERR_INVALID_ARG_TYPE]: The first argument must be one of type string or Buffer. Received type object
谁能告诉我如何正确地从 MySQL 数据库发送大量数据作为响应?
@akram 我按照你的建议使用了fs 包。我使用下一个代码来创建 JSON 文件:
await pool.query(sql_statement, binds, function (error, results) {
if (error) throw error;
fs.writeFile("information.json", results, 'utf8', function (error) {
if(error) throw error;
});
});
此代码创建 json 文件,每月数据池大小约为 3.5 MB。在编辑器中,我有下一条消息:
This document contains very long lines. Soft wraps were forcibly enable to improve editor performance.
在我看来太奇怪了。
【问题讨论】:
-
你下载一个文件,让浏览器处理它。
-
IMO 发送大数据的最佳方式不是发送,而是更改应用程序的业务逻辑。不要用千兆字节的数据打扰浏览器 - 更好地在服务器上处理它(DataBase 服务器将是最好的解决方案,而不是 Node.js),并且只推送透视数据以进行可视化
-
@DaveNewton 我考虑过使用
cron创建*.json.gz静态文件。问题是我使用的 MySQL 表有 2000 万条记录,并且每小时都会补充新的记录。我们也不知道用户会选择什么时间段。我们每次都要重新计票。所以就我而言,这不是解决方案。 -
@grapes 实际上在 node.js 端没有计算。我只需要从 mysql 表中获取每月数据池并将其显示在地图上。 MySQL 在几秒钟内返回我 227011 行(每月数据池),因为我使用索引和分区。我向你保证,业务逻辑很好。你有什么其他想法吗我的朋友? :)
-
如果没有办法减少数据集,发送给客户端,为什么不优化呢?想过改变 json->csv 吗?它不仅将大小至少减少 2,而且还允许流式传输(意味着您可以在客户端逐行处理,而无需在内存中获取全文并对其进行解析)。另一个想法 - 使用 web socket 协议而不是 http。在流数据的上下文中
标签: javascript node.js json