【问题标题】:How send huge datapool in response?如何发送巨大的数据池作为响应?
【发布时间】: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.

该 json 文件还包含:

在我看来太奇怪了。

【问题讨论】:

  • 你下载一个文件,让浏览器处理它。
  • 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


【解决方案1】:

尝试使用 JSONStream https://github.com/dominictarr/JSONStream,我认为可以解决您的问题,JSONStream 文档中有一个示例

【讨论】:

  • 我有点困惑。在文档中,所有示例都解析准备好的 JSON 文件。就我而言,我没有 JSON 文件。我刚刚从数据库中获取数据。能给我看个小例子吗?
  • @NurzhanNogerbek,将我们的结果添加到文件 fs.writeFile('myjsonfile.json', json, 'utf8', results);通过 jsonStream 阅读 myjsonfile.json
  • 你能再看看我的帖子吗?我按照您的建议使用了fs 包。我注意到一些奇怪的行为。
猜你喜欢
  • 2019-05-01
  • 1970-01-01
  • 1970-01-01
  • 2019-04-27
  • 2021-01-17
  • 1970-01-01
  • 2016-10-19
  • 1970-01-01
  • 2020-09-06
相关资源
最近更新 更多