变体与 JSON 字符串有何不同?

重要

此功能目前以公共预览版提供。

本文介绍使用变体数据类型时的行为变化以及语法和语义的差异。 本文假设你知道如何在 Azure Databricks 上处理 JSON 字符串数据。 对于 Azure Databricks 的新用户,在存储需要灵活更改或未知架构的半结构化数据时,应使用 JSON 字符串的变体。 请参阅对半结构化数据建模

在 Databricks Runtime 15.3 及更高版本中,可以使用变体数据类型来编码和查询半结构化数据。 Databricks 建议使用变体来替代使用 JSON 字符串存储半结构化数据的做法。 变体的读写性能提高使其能够在某些用例中取代原生的 Spark 复杂类型,例如结构和数组。

如何查询变体数据?

变体数据使用相同的运算符来查询字段、子字段和数组元素。

若要查询某个字段,请使用 :。 例如 column_name:field_name

若要查询某个子字段,请使用 .。 例如 column_name:field_name.subfield_name

若要查询数组元素,请使用 [n],其中 n 是元素的整数索引值。 例如,若要查询数组中的第一个值,请使用 column_name:array_name[0]

从 JSON 字符串升级到变体时,以下差异可能会破坏现有查询:

  • 所有变体路径元素均以区分大小写的方式进行匹配。 JSON 字符串不区分大小写。 这意味着,对于变体,column_name:FIELD_NAMEcolumn_name:field_name 在存储的数据中查找不同的字段。
  • [*] 语法不支持识别或解包数组中的所有元素。
  • 变体以不同于 JSON 字符串的方式对 NULL 值进行编码。 请参阅变量 null 规则
  • 变体列在某些操作中有局限性。 请参阅限制

在 JSON 字符串与变体之间来回转换

在 Databricks Runtime 15.3 及更高版本中,to_json 函数具有将 VARIANT 类型强制转换为 JSON 字符串的附加功能。 将 VARIANT 转换为 JSON 字符串时,将忽略选项。 请参阅 to_json

函数 parse_jsonSQLPython)将 JSON 字符串转换为 VARIANT 类型。 虽然 parse_json(json_string_column)to_json(variant_column) 的逻辑反函数,但以下转换规则描述了为什么它不是确切的反函数:

  • 空白字符不会完美保留。
  • 键的排序是任意的。
  • 可能会截断数字中的尾随零。

SQL

SELECT parse_json('{"key": 1, "data": [2, 3, "str"]}');

Python

spark.range(1).select(parse_json(lit('{"key": 1, "data": [2, 3, "str"]}'))).display()

如果 JSON 字符串格式不正确、超出变体大小限制或无效,该 parse_json 函数将返回错误。 使用try_parse_json函数(SQLPython)以返回NULL当发生解析错误时。

SQL

SELECT try_parse_json('{"a" : invalid, "b" : 2}');

Python

spark.range(1).select(try_parse_json(lit('{"a" : invalid, "b" : 2}'))).display()

用于处理变体的 SQL 函数有哪些?

Databricks Runtime 15.3 及更高版本中提供的 Apache Spark SQL 函数提供了与变体数据交互的方法。 下表包括新函数、对应的 JSON 字符串函数以及行为差异的说明。

变体以不同于 JSON 字符串的方式处理强制转换和 NULL。 请参阅变体类型强制转换规则变体 null 规则

注意

若要将这些函数与 PySpark 数据帧一起使用,请从 pyspark.sql.functions 导入它们。

变体函数 JSON 字符串函数 备注
variant_get castget_json_object 采用表达式、路径和类型。 遵循变体路径、强制转换和 null 值的所有规则。
try_variant_get try_castget_json_object 采用表达式、路径和类型。 遵循变体路径、强制转换和 null 值的所有规则。
is_variant_null 为 null 检查表达式是否存储了 VARIANT 编码的 NULL。 使用 is null 检查输入表达式是否为 NULL
schema_of_variant schema_of_json 确定 ARRAY<elementType> 的架构时,如果在数据中发现冲突的类型,则 elementType 可能被推理为 VARIANT
schema_of_variant_agg schema_of_json_agg 未识别到最不常用的类型时,类型将派生为 VARIANT
variant_explode explode 输出 poskeyvalue 列。 当分解数组时,输出键始终为 null。
variant_explode_outer explode_outer 输出 poskeyvalue 列。 当分解数组时,输出键始终为 null。