Skip to content

Commit

Permalink
[feature][plugin][jsonreader] Add support for multiline json file (#1140
Browse files Browse the repository at this point in the history
)

1. Implement support for reading multi-line JSON files.
2. Introduce a `singleLine` option to toggle between reading single-line and multi-line JSON files, with the default set to single-line.
  • Loading branch information
wgzhao committed Sep 23, 2024
1 parent d6e586c commit d057a05
Show file tree
Hide file tree
Showing 4 changed files with 222 additions and 78 deletions.
126 changes: 111 additions & 15 deletions docs/reader/jsonfilereader.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,17 +13,9 @@ JSON File Reader 提供了读取本地文件系统数据存储的能力。
其中 `/tmp/test*.json` 为同一个 json 文件的多个复制,内容如下:

```json
{
"name": "zhangshan",
"id": 19890604,
"age": 12,
"score": {
"math": 92.5,
"english": 97.5,
"chinese": 95
},
"pubdate": "2020-09-05"
}
{"name": "zhangshan","id": 19890604,"age": 12,"score": {"math": 92.5,"english": 97.5,"chinese": 95},"pubdate": "2020-09-05"}
{"name": "lisi","id": 19890605,"age": 12,"score": {"math": 90.5,"english": 77.5,"chinese": 90},"pubdate": "2020-09-05"}
{"name": "wangwu","id": 19890606,"age": 12,"score": {"math": 89,"english": 100,"chinese": 92},"pubdate": "2020-09-05"}
```

## 参数说明
Expand All @@ -35,14 +27,22 @@ JSON File Reader 提供了读取本地文件系统数据存储的能力。
| fieldDelimiter || string | `,` | 描述:读取的字段分隔符 |
| compress || string || 文本压缩类型,默认不填写意味着没有压缩。支持压缩类型为zip、gzip、bzip2 |
| encoding || string | utf-8 | 读取文件的编码配置 |
| singleLine || boolean | true | 每条数据是否为一行, 详见下文 |

### path

本地文件系统的路径信息,注意这里可以支持填写多个路径
本地文件系统的路径信息,注意这里可以支持填写多个路径,比如:

- 当指定单个本地文件,JsonFileReader暂时只能使用单线程进行数据抽取。
- 当指定多个本地文件,JsonFileReader支持使用多线程进行数据抽取。线程并发数通过通道数指定。
- 当指定通配符,JsonFileReader尝试遍历出多个文件信息。例如: 指定`/*` 代表读取/目录下所有的文件,指定`/bazhen/*` 代表读取bazhen目录下游所有的文件。 JsonFileReader目前只支持 `*` 作为文件通配符。
```json
{
"path": [
"/var/ftp/test.json", // 读取 /var/ftp 目录下的 test.json 文件
"/var/tmp/*.json", // 读取 /var/tmp 目录下所有 json 文件
"/public/ftp", // 读取 /public/ftp 目录下所有文件, 如果 ftp 是文件的话,则直接读取
"/public/a??.json" // 读取 /public 目录下所有 a 开头,后面跟两个字符,最后是 json 结尾的文件
]
}
```

特别需要注意的是,如果Path指定的路径下没有符合匹配的文件抽取,Addax将报错。

Expand All @@ -52,6 +52,102 @@ JSON File Reader 提供了读取本地文件系统数据存储的能力。

对于用户指定Column信息,type必须填写,index/value 必须选择其一

### singleLine

使用 JSON 格式存储数据,业界有两种方式,一种是每行一个 JSON 对象,也就是 `Single Line JSON(aka. JSONL or JSON Lines)`;
另一种是整个文件是一个 JSON 数组,每个元素是一个 JSON 对象,也就是 `Multiline JSON`

Addax 默认支持每行一个 JSON 对象的格式,即 `singeLine = true`, 在这种情况下,要注意的是:

1. 每行 JSON 对象的末尾不能有逗号,否则会解析失败。
2. 一个JSON 对象不能跨行,否则会解析失败。

如果数据是整个文件是一个 JSON 数组,每个元素是一个 JSON 对象,需要设置 `singeLine``false`
假设上述列子中的数据用下面的格式表示:

```json
{
"result": [
{
"name": "zhangshan",
"id": 19890604,
"age": 12,
"score": {
"math": 92.5,
"english": 97.5,
"chinese": 95
},
"pubdate": "2020-09-05"
},
{
"name": "lisi",
"id": 19890605,
"age": 12,
"score": {
"math": 90.5,
"english": 77.5,
"chinese": 90
},
"pubdate": "2020-09-05"
},
{
"name": "wangwu",
"id": 19890606,
"age": 12,
"score": {
"math": 89,
"english": 100,
"chinese": 92
},
"pubdate": "2020-09-05"
}
]
}
```

因为这种格式是合法的 JSON 格式,因此每个 JSON 对象可以跨行。相应的,这类数据读取时,其 `path` 配置应该如下填写:

```json
{
"singleLine": false,
"column": [
{
"index": "$.result[*].id",
"type": "long"
},
{
"index": "$.result[*].name",
"type": "string"
},
{
"index": "$.result[*].age",
"type": "long"
},
{
"index": "$.result[*].score.math",
"type": "double"
},
{
"index": "$.result[*].score.english",
"type": "double"
},
{
"index": "$..result[*].pubdate",
"type": "date"
},
{
"type": "string",
"value": "constant string"
}
]
}
```

更详细的使用说明请参考 [Jayway JsonPath](https://github.com/json-path/JsonPath) 的语法。

注意: 这种数据在一个 JSON 数组里时,程序只能采取将整个文件读取到内存中,然后解析的方式,因此不适合大文件的读取。
对于大文件的读取,建议使用每行一个 JSON 对象的格式,也就是 `Single Line JSON` 的格式,这种格式可以采取逐行读取的方式,不会占用太多内存。

## 类型转换

| Addax 内部类型 | 本地文件 数据类型 |
Expand Down
Loading

0 comments on commit d057a05

Please sign in to comment.