如何读取具有不同数据类型的大型 JSON 文件

Posted

技术标签:

【中文标题】如何读取具有不同数据类型的大型 JSON 文件【英文标题】:How to read large JSON files that have different data types in it 【发布时间】:2021-09-20 12:08:01 【问题描述】:

我正在创建一个 npm 包,它将读取 json 文件,然后根据一些预定义的 json-schemas 验证内容,当我针对小尺寸 (~1MB) 文件进行测试时一切正常,但当我开始读取 50MB 和更大尺寸的东西开始失败, 就像当我到达解析文件的代码时,Allocation failed - javascript heap out of memory 被抛出,所以我尝试增加节点内存的大小node --max-old-space-size=4096,但现在解析需要很长时间(等了将近一个小时,但什么也没发生)。

下面是 json 文件的样子:

[
    "numberVerification": [
        
            "longNumber": 281474976710655
        
    ]
,

    "metaData": [
        
            "name": "nodes",
            "elementCount": 155,
            "idCounter": 155,
            "version": "1.0",
        ,
        
            "name": "edges",
            "elementCount": 312,
            "idCounter": 312,
            "version": "1.0",
        ,
        
            "name": "networkAttributes",
            "elementCount": 14,
            "idCounter": 14,
            "version": "1.0",
        ,
        
            "name": "nodeAttributes",
            "elementCount": 330,
            "idCounter": 330,
            "version": "1.0",
        ,
        
            "name": "edgeAttributes",
            "elementCount": 3120,
            "idCounter": 3120,
            "version": "1.0",
        ,
        
            "name": "cartesianLayout",
            "elementCount": 155,
            "idCounter": 156
        ,
    ]
,

    "nodes": [
        
            "@id": 0,
            "n": "TYK2",
            "r": "uniprot:P29597"
        ,
        
            "@id": 1,
            "n": "ISGF3 complex",
            "r": "signor:SIGNOR-C124"
        ,
        ...
    ]
,

    "edges": [
        
            "@id": 0,
            "s": 0,
            "t": 1,
            "i": "up-regulates activity"
        ,
        
            "@id": 1,
            "s": 2,
            "t": 1,
            "i": "up-regulates activity"
        ,
        ...
    ]
,

    "nodeAttributes": [
        
            "po": 0,
            "n": "type",
            "v": "protein"
        ,
        
            "po": 0,
            "n": "location",
            "v": "cytoplasm"
        ,
        ...
    ]
,

    "edgeAttributes": [
        
            "po": 0,
            "n": "citation",
            "v": [
                "pubmed:15120645"
            ],
            "d": "list_of_string"
        ,
        
            "po": 0,
            "n": "mechanism",
            "v": "phosphorylation"
        ,
        ...
    ]
,

    "cartesianLayout": [
    
        "node": 0,
        "x": 97.73626669665249,
        "y": -114.99468800778627
    ,
    
        "node": 1,
        "x": 307.72737757573987,
        "y": 4.091777979752425
    ,
    ...
]
,

    "status": [
        
            "error": "",
            "success": true
        
    ]
]

如您所见,主数组的每个对象都是不同的类型。

我使用 fs.readFileSync 读取 json 文件,然后使用 JSON.parse() 解析整个文件,但后来我发现为了读取大 json 文件我需要使用 streams 但现在我应该怎么做验证json-schema?我还对数据进行了一些额外的自定义验证,例如检查@id 属性是否唯一,验证node(在笛卡尔布局数组中)、ts(在边缘数组中)属性是否为指向nodes数组中的真实@id,然后我想对数据做一些进一步的统计。

那么有没有办法读取大型 json 文件并对其进行解析,如果适用,我怎样才能保持验证运行?以及我需要使用任何外部提供者的统计部分吗?

json 文件是从第 3 方生成的,因此我无法对数据的结构及其在其中的呈现方式做任何事情。

如果有人希望我提供任何其他信息,请告诉我,感谢您的帮助。

【问题讨论】:

【参考方案1】:

要在流中使用 JSON 对象,您可以使用 JSONStream npm 库(有关用法,请参阅文档)。您必须使用 JSONPath 语法来到达所需的节点(包括根节点,如有必要)并根据您的规则执行“滚动”验证。

【讨论】:

以上是关于如何读取具有不同数据类型的大型 JSON 文件的主要内容,如果未能解决你的问题,请参考以下文章

拆分大型 json 文件并将每个部分分配给一个进程

如何解析具有相同键的不同数据类型的改造对象的json数组

R读取大型数据集内存不足如何解决,如果利用Linux有啥有效方法吗?

从大型 JSON 中读取特定字段并导入 Pandas 数据框

找不到“object”类型的不同支持对象“[object Object]”。仅支持在从 JSON 文件读取和解析数据时绑定到 Iterables

读取和处理多个大型数据文件的良好做法?