JSONObjectEachRow
输入 | 输出 | 别名 |
---|---|---|
✔ | ✔ |
描述
在这种格式中,所有数据都表示为单个 JSON 对象,其中每一行都表示为该对象的单独字段,类似于 JSONEachRow
格式。
示例用法
基本示例
给定一些 JSON
{
"row_1": {"num": 42, "str": "hello", "arr": [0,1]},
"row_2": {"num": 43, "str": "hello", "arr": [0,1,2]},
"row_3": {"num": 44, "str": "hello", "arr": [0,1,2,3]}
}
要使用对象名称作为列值,您可以使用特殊设置 format_json_object_each_row_column_for_object_name
。此设置的值设置为列的名称,该列用作结果对象中行的 JSON 键。
输出
假设我们有一个名为 test
的表,其中包含两列
┌─object_name─┬─number─┐
│ first_obj │ 1 │
│ second_obj │ 2 │
│ third_obj │ 3 │
└─────────────┴────────┘
让我们以 JSONObjectEachRow
格式输出它,并使用 format_json_object_each_row_column_for_object_name
设置
SELECT * FROM test SETTINGS format_json_object_each_row_column_for_object_name='object_name'
{
"first_obj": {"number": 1},
"second_obj": {"number": 2},
"third_obj": {"number": 3}
}
输入
假设我们将上一个示例的输出存储在一个名为 data.json
的文件中
SELECT * FROM file('data.json', JSONObjectEachRow, 'object_name String, number UInt64') SETTINGS format_json_object_each_row_column_for_object_name='object_name'
┌─object_name─┬─number─┐
│ first_obj │ 1 │
│ second_obj │ 2 │
│ third_obj │ 3 │
└─────────────┴────────┘
它也适用于 schema 推断
DESCRIBE file('data.json', JSONObjectEachRow) SETTING format_json_object_each_row_column_for_object_name='object_name'
┌─name────────┬─type────────────┐
│ object_name │ String │
│ number │ Nullable(Int64) │
└─────────────┴─────────────────┘
插入数据
INSERT INTO UserActivity FORMAT JSONEachRow {"PageViews":5, "UserID":"4324182021466249494", "Duration":146,"Sign":-1} {"UserID":"4324182021466249494","PageViews":6,"Duration":185,"Sign":1}
ClickHouse 允许
- 对象中键值对的任何顺序。
- 省略某些值。
ClickHouse 忽略元素之间的空格和对象之后的逗号。您可以将所有对象放在一行中。您不必用换行符分隔它们。
省略值处理
ClickHouse 将省略值替换为相应数据类型的默认值。
如果指定了 DEFAULT expr
,则 ClickHouse 会根据 input_format_defaults_for_omitted_fields 设置使用不同的替换规则。
考虑下表
CREATE TABLE IF NOT EXISTS example_table
(
x UInt32,
a DEFAULT x * 2
) ENGINE = Memory;
- 如果
input_format_defaults_for_omitted_fields = 0
,则x
和a
的默认值等于0
(作为UInt32
数据类型的默认值)。 - 如果
input_format_defaults_for_omitted_fields = 1
,则x
的默认值等于0
,但a
的默认值等于x * 2
。
当使用 input_format_defaults_for_omitted_fields = 1
插入数据时,与使用 input_format_defaults_for_omitted_fields = 0
插入数据相比,ClickHouse 会消耗更多的计算资源。
选择数据
以 UserActivity
表为例
┌──────────────UserID─┬─PageViews─┬─Duration─┬─Sign─┐
│ 4324182021466249494 │ 5 │ 146 │ -1 │
│ 4324182021466249494 │ 6 │ 185 │ 1 │
└─────────────────────┴───────────┴──────────┴──────┘
查询 SELECT * FROM UserActivity FORMAT JSONEachRow
返回
{"UserID":"4324182021466249494","PageViews":5,"Duration":146,"Sign":-1}
{"UserID":"4324182021466249494","PageViews":6,"Duration":185,"Sign":1}
与 JSON 格式不同,不会替换无效的 UTF-8 序列。值的转义方式与 JSON
相同。
任何字节集都可以在字符串中输出。如果您确定表中的数据可以格式化为 JSON 而不会丢失任何信息,请使用 JSONEachRow
格式。
嵌套结构的使用
如果您的表具有 Nested
数据类型列,则可以插入具有相同结构的 JSON 数据。使用 input_format_import_nested_json 设置启用此功能。
例如,考虑下表
CREATE TABLE json_each_row_nested (n Nested (s String, i Int32) ) ENGINE = Memory
正如您在 Nested
数据类型描述中看到的那样,ClickHouse 将嵌套结构的每个组件视为一个单独的列(对于我们的表,为 n.s
和 n.i
)。您可以按以下方式插入数据
INSERT INTO json_each_row_nested FORMAT JSONEachRow {"n.s": ["abc", "def"], "n.i": [1, 23]}
要将数据作为分层 JSON 对象插入,请设置 input_format_import_nested_json=1
。
{
"n": {
"s": ["abc", "def"],
"i": [1, 23]
}
}
如果没有此设置,ClickHouse 将抛出异常。
SELECT name, value FROM system.settings WHERE name = 'input_format_import_nested_json'
┌─name────────────────────────────┬─value─┐
│ input_format_import_nested_json │ 0 │
└─────────────────────────────────┴───────┘
INSERT INTO json_each_row_nested FORMAT JSONEachRow {"n": {"s": ["abc", "def"], "i": [1, 23]}}
Code: 117. DB::Exception: Unknown field found while parsing JSONEachRow format: n: (at row 1)
SET input_format_import_nested_json=1
INSERT INTO json_each_row_nested FORMAT JSONEachRow {"n": {"s": ["abc", "def"], "i": [1, 23]}}
SELECT * FROM json_each_row_nested
┌─n.s───────────┬─n.i────┐
│ ['abc','def'] │ [1,23] │
└───────────────┴────────┘