LOGO OA教程 ERP教程 模切知识交流 PMS教程 CRM教程 开发文档 其他文档  
 
网站管理员

GB级比较大的JSON怎么读取解析呢?

admin
2024年3月28日 23:5 本文热度 527

比较大的JSON怎么读取呢?,一两个G的json,open直接读取会卡死吧。

这是某群前些天某人的一个提问以及我的回答。

这个话题让我想到2016年,客户扔了个10G的json文件过来,BA想提取里面的信息,却发现Windows下没有合适的工具打开它,问我咋办,我当时是用grep处理的。后来知道了jq[1]

jq 是一个轻量级且灵活的命令行JSON处理器,它被设计来处理JSON数据,就像sed用于处理文本数据一样。你可以使用jq来切片、过滤、映射和转换结构化数据,其语法简洁,易于上手。

jq是一个强大的工具,特别适合需要处理和转换JSON数据的开发者和系统管理员使用。它的设计哲学和功能集使得它成为处理JSON数据的不二之选。

其实这个不二之选,自从有了DuckDB,就不成立了。相比较jq,还是DuckDB更香。

其实我之前就向大家介绍了DuckDB的文章,探索DuckDB:使用SQL和DuckDB分析JSON数据

今天看到一篇文章,和我的想法不谋而合。DuckDB as the New jq[2] 

以下是全文,

最近,我对DuckDB[3]项目(一个面向数据应用的SQLite[4])产生了兴趣。它最令人惊叹的特性之一是包含了许多数据导入器,而且不需要额外的依赖。这意味着它可以直接将JSON作为数据库表读取和解析,同时还支持许多其他格式。

我日常工作中大量使用JSON,经常使用 jq[5]来探索文档。我喜欢jq,但我发现它难以使用。它的语法非常强大,但我每次想要做超出仅仅选择字段的操作时,都必须研究文档。

一旦我了解到DuckDB可以直接将JSON文件读取到内存中,我就意识到我可以用它来做很多我目前使用jq做的事情。与复杂且自定义的jq语法相比,我对SQL非常熟悉,并且几乎每天都在使用。

这里有一个例子:

首先,我们获取一些示例JSON来玩。我使用GitHub API获取了golang组织的仓库信息:

% curl 'https://api.github.com/orgs/golang/repos' > repos.json

现在,作为一个示例问题来回答,让我们获取一些关于使用的开源许可证类型的统计信息。

JSON结构如下所示:

[
  {
    "id": 1914329,
    "name": "gddo",
    "license": {
      "key": "bsd-3-clause",
      "name": "BSD 3-Clause \"New\" or \"Revised\" License",
      ...
    },
    ...
  },
  {
    "id": 11440704,
    "name": "glog",
    "license": {
      "key": "apache-2.0",
      "name": "Apache License 2.0",
      ...
    },
    ...
  },
  ...
]

这可能不是最好的方法,但在我搜索并阅读了一些关于如何在jq中做到这一点的文档后,我拼凑出了以下内容:

 % cat repos.json | jq 'group_by(.license.key)
  | map({license: .[0].license.key, count: length})
  | sort_by(.count)
  | reverse'
[
  {
    "license": "bsd-3-clause",
    "count": 23
  },
  {
    "license": "apache-2.0",
    "count": 5
  },
  {
    "license": null,
    "count": 2
  }
]

在DuckDB中使用SQL是这样的:

% duckdb -c "
  select license->>'key' as license, count(*) as count 
  from 'repos.json' 
  group by 1 
  order by count desc"
┌──────────────┬───────┐
│   license    │ count │
│   varchar    │ int64 │
├──────────────┼───────┤
│ bsd-3-clause │    23 │
│ apache-2.0   │     5 │
│              │     2 │
└──────────────┴───────┘

对我来说,这个SQL要简单得多,我能够不查看任何文档就写出来。唯一的难点是使用->>操作符查询嵌套的JSON。这种语法与PostgreSQL JSON Functions[6]相同,所以我对此很熟悉。

如果我们确实需要以JSON格式输出,DuckDB提供了一个标志来实现这一点:

% duckdb -json -c "
  select license->>'key' as license, count(*) as count 
  from 'repos.json' 
  group by 1 
  order by count desc"
[{"license":"bsd-3-clause","count":23},{"license":"apache-2.0","count":5},{"license":null,"count":2}]

我们甚至可以在DuckDB完成重活之后,使用jq来美化输出:

% duckdb -json -c "
  select license->>'key' as license, count(*) as count 
  from 'repos.json' 
  group by 1 
  order by count desc" | jq
[
  {
    "license": "bsd-3-clause",
    "count": 23
  },
  {
    "license": "apache-2.0",
    "count": 5
  },
  {
    "license": null,
    "count": 2
  }
]

JSON只是导入DuckDB数据的多种方式之一。这种方法同样适用于CSV、parquet、Excel文件等。

我可以选择创建表并本地持久化,但通常我只是在查询数据,不需要持久化。

想要了解更多关于DuckDB出色的JSON支持,请阅读这篇博客文章:一次一个向量地撕裂深层嵌套的JSON[7]

更新:

我还了解到,DuckDB可以直接从URL读取JSON,而不仅仅是本地文件:

% duckdb -c "
  select license->>'key' as license, count(*) as count 
  from read_json('https://api.github.com/orgs/golang/repos')  
  group by 1 
  order by count desc"

引用链接

[1] jq: https://jqlang.github.io/jq/
[2] DuckDB as the New jq: https://www.pgrs.net/2024/03/21/duckdb-as-the-new-jq/
[3] DuckDB: https://duckdb.org/
[4] SQLite: https://www.sqlite.org/
[5] jq: https://jqlang.github.io/jq/
[6] PostgreSQL JSON Functions: https://www.postgresql.org/docs/current/functions-json.html
[7] 一次一个向量地撕裂深层嵌套的JSON: https://duckdb.org/2023/03/03/json.html


该文章在 2024/3/28 23:05:22 编辑过
关键字查询
相关文章
正在查询...
点晴ERP是一款针对中小制造业的专业生产管理软件系统,系统成熟度和易用性得到了国内大量中小企业的青睐。
点晴PMS码头管理系统主要针对港口码头集装箱与散货日常运作、调度、堆场、车队、财务费用、相关报表等业务管理,结合码头的业务特点,围绕调度、堆场作业而开发的。集技术的先进性、管理的有效性于一体,是物流码头及其他港口类企业的高效ERP管理信息系统。
点晴WMS仓储管理系统提供了货物产品管理,销售管理,采购管理,仓储管理,仓库管理,保质期管理,货位管理,库位管理,生产管理,WMS管理系统,标签打印,条形码,二维码管理,批号管理软件。
点晴免费OA是一款软件和通用服务都免费,不限功能、不限时间、不限用户的免费OA协同办公管理系统。
Copyright 2010-2024 ClickSun All Rights Reserved