在 Node JS 中处理 10 GB JSON 文件
Posted
技术标签:
【中文标题】在 Node JS 中处理 10 GB JSON 文件【英文标题】:Process 10 GB JSON file in Node JS 【发布时间】:2021-10-26 05:26:58 【问题描述】:我有一个json文件,该文件的结构如下:
"orders":[
"id": 876876876,
"app_id":580714,
"client_details": ,
"discount_codes": [],
"line_items": [
"id": 466157049,
...
],
......
,
"id": 47844583,
"app_id":580714,
"client_details": ,
"discount_codes": [],
"line_items": [
"id": 466157049,
...
],
....
,
...,
...,
...
]
这个数组可以包含超过 100 万(100 万)个对象。目前我需要:
查找具有订单 ID 的对象 订单总数 获取带有订单id和数量限制的订单我正在使用以下代码:
return new Promise((resolve, reject) =>
var orders = []
var getStream = function ()
var stream = fs.createReadStream(file_path, encoding: 'utf8' ),
parser = JSONStream.parse('*');
return stream.pipe(parser);
;
getStream()
.pipe(es.mapSync(function (data)
orders = data
)) .on('end', function()
resolve(orders)
)
)
但这会使系统挂起。另外,我也使用了以下命令:
node --max-old-space-size=8192 index.js
但这也行不通。谁能帮我处理这么大的json文件。
已编辑: 现在文件大小为 850MB,我正在使用以下代码:
return new Promise((resolve, reject) =>
var data = ''
var reader_stream = fs.createReadStream(file_path)
reader_stream.setEncoding('UTF8')
reader_stream.on('data', function(chunk)
data += chunk
)
reader_stream.on('end',function()
try
const orders_result = JSON.parse(data)
var order_count = (orders_result.orders)
resolve(
"count": order_count.length
)
catch(err)
console.log(err)
)
reader_stream.on('error', function(err)
console.log(err.stack)
reject(err.stack)
)
)
并得到以下错误
未捕获的异常:RangeError:无效的字符串长度
【问题讨论】:
当您拥有如此大量的数据时,将其存储在数据库中可能是一个好主意。您可以从中查询您需要的内容。 我知道@Sandsten,但 DB 不是这里的选项。 什么是“不工作”? @DeepKakkar - 10GB JSON 需要 >10GB 内存用于您的节点进程 - 我认为您的节点进程在 64 位操作系统中是 64 位的,对吧? @DeepKakkar,我想你正在寻找这个question 并且可能在那里重复。 【参考方案1】:JSON.parse
需要将整个文件读入内存,包括应用程序不需要的部分。一种方法是使用类似 SAX 的解析器,例如 clarinet。这些解析器不会将整个文件读入内存,它们会在解析过程中生成事件。您需要处理这些事件以检查数据是否感兴趣,并仅存储您实际需要的信息。
这会减少解析过程所需的内存量,但不是那么方便。你的操作听起来你不需要所有的数据,所以也许你很幸运,一个精简的版本可以放入内存。
【讨论】:
我已经编辑了我的问题,现在文件大小只有 850 MB,但出现错误为 __RangeError: Invalid string length @DeepKakkar 这个答案应该仍然可以解决问题。字符串有大小限制,因此您将不得不使用真正的数据库,将数据拆分为较小的文件(将它们分类到多个文件夹中?),或者使用解析器,就像这个答案中的解析器一样。 在不知道您的确切设置的情况下,一个 850MB 的字符串仍然可能超出您的应用程序的处理能力。这也取决于您的 node.js 版本,请参阅答案(尤其是评论):***.com/a/47781288/431715 我使用的是v14.15.0版本的Node js 我没有得到示例代码来使用,因此我可以获得对象进行处理。例如var stream = require("clarinet").createStream(options);那里有什么选择?以上是关于在 Node JS 中处理 10 GB JSON 文件的主要内容,如果未能解决你的问题,请参考以下文章
为啥 node.js 配置文件的大小会是数 GB? webstorm 处理的方式
Node.js Express 应用程序在负载测试下花费太多时间来处理出站 HTTP 请求