Skip to main content
前文的 JSON 数据加载示例都默认使用 JSONEachRow (NDJSON) 。这种格式会将每个 JSON 行中的键读取为列。例如:
虽然这通常是最常用的 JSON 格式,但你也会遇到其他格式,或者需要将 JSON 作为单个对象来读取。 下面我们提供了一些示例,说明如何以其他常见格式读取和加载 JSON。

将 JSON 作为对象读取

前面的示例展示了 JSONEachRow 如何读取以换行分隔的 JSON:每一行都会作为单独的对象读取,映射到表中的一行,而每个键则映射到一列。这非常适合 JSON 结构可预测、且每列只有单一类型的场景。 相比之下,JSONAsObject 会将每一行视为一个单独的 JSON 对象,并将其存储在单个列中,类型为 JSON,因此更适合嵌套的 JSON 载荷,以及键是动态的、且可能对应多种类型的场景。 对于按行 insert,请使用 JSONEachRow;而在存储灵活或动态的 JSON 数据时,请使用 JSONAsObject 对比上面的示例和下面这个查询:后者会将相同的数据按每行一个 JSON 对象的方式读取:
JSONAsObject 可用于通过单个 JSON 对象列向表中插入行,例如:
在对象结构不一致的情况下,JSONAsObject 格式对于读取以换行分隔的 JSON 也很有用。例如,如果某个键在不同行中的类型会发生变化 (有时是字符串,有时又是对象) 。在这种情况下,ClickHouse 无法使用 JSONEachRow 推断出稳定的 schema,而 JSONAsObject 则允许在不强制执行严格类型检查的情况下摄取数据,将每个 JSON 行作为整体存储在单个列中。例如,请看 JSONEachRow 如何在下面的示例中失败:
相反,在这种情况下可以使用 JSONAsObject,因为 JSON 类型允许同一子列对应多种类型。

JSON 对象数组

JSON 数据最常见的一种形式,是在 JSON 数组中包含一组 JSON 对象,如此示例所示:
下面为这类数据创建一个表:
要导入一组 JSON 对象,可以使用 JSONEachRow 格式 (从 list.json 文件中插入数据) :
我们使用了 FROM INFILE 子句从本地文件加载数据,可以看到导入已成功:

JSON 对象键

在某些情况下,JSON 对象列表也可以编码为对象属性,而不是数组元素 (示例见 objects.json) :
ClickHouse 可以使用 JSONObjectEachRow 格式从此类数据中导入数据:

指定父对象的键值

假设我们还想将父对象键中的值保存到表中。在这种情况下,我们可以使用以下选项来指定用于保存键值的列名:
现在,我们可以使用 file() 函数查看将从原始 JSON 文件加载哪些数据:
请注意,id 列已正确填入键值。

JSON 数组

有时,为了节省空间,JSON 文件会采用数组而不是对象的编码方式。在这种情况下,我们处理的是一份 JSON 数组列表
在这种情况下,ClickHouse 会加载这些数据,并根据数组中的顺序将每个值对应到相应的列。为此,我们使用 JSONCompactEachRow 格式:

从 JSON 数组中导入各个列

在某些情况下,数据可以按列而非按行编码。在这种情况下,外层 JSON 对象包含各列及其值。请查看以下文件
ClickHouse 使用 JSONColumns 格式来解析如下格式的数据:
如果处理的是列数组而不是对象,也支持使用更紧凑的 JSONCompactColumns 格式:

保存 JSON 对象而不解析

在某些情况下,你可能希望将 JSON 对象保存到单个 String (或 JSON) 列中,而不是对其进行解析。在处理由不同结构的 JSON 对象组成的列表时,这会很有用。以这个文件为例,其中父列表内包含多个不同的 JSON 对象:
我们希望将原始 JSON 对象保存到下列表中:
现在,我们可以使用 JSONAsString 格式将文件中的数据加载到该表中,从而保留 JSON 对象,而不对其进行解析:
我们可以使用 JSON functions 对已保存的对象进行查询:
请注意,对于按每行一个 JSON 对象组织的文件 (通常与 JSONEachRow 格式一起使用) ,JSONAsString 也完全可以正常工作。

嵌套对象的 schema

在处理嵌套 JSON 对象时,我们还可以显式定义 schema,并使用复杂类型 (ArrayJSONTuple) 来加载数据:

访问嵌套 JSON 对象

启用以下设置选项后,我们就可以引用嵌套 JSON 键
这样我们就可以使用点表示法来引用嵌套 JSON 对象的键 (注意要用反引号将这些键括起来才能生效) :
这样,我们就可以将嵌套的 JSON 对象展平,或者提取其中的一些嵌套值,将其另存为单独的列。

跳过未知列

默认情况下,ClickHouse 在导入 JSON 数据时会忽略未知列。现在尝试将原始文件导入不包含 month 列的表中:
我们仍然可以将包含 3 列的原始 JSON 数据插入这个表中:
ClickHouse 在导入时会忽略未知列。可通过 input_format_skip_unknown_fields 设置项禁用此行为:
当 JSON 与表列结构不一致时,ClickHouse 会抛出异常。

BSON

ClickHouse 支持将数据导出为 BSON 编码文件,也支持从这类文件导入数据。一些 DBMS 会使用这种格式,例如 MongoDB 数据库。 要导入 BSON 数据,我们使用 BSONEachRow 格式。下面从这个 BSON 文件导入数据:
我们也可以使用相同的格式导出到 BSON 文件:
之后,我们的数据会导出到 out.bson 文件中。
最后修改于 2026年7月3日