變體與 JSON 字串有什麼不同?

本文說明使用 Variant 數據類型時,語法和語意的行為變更和差異。 本文假設您已熟悉在 Azure Databricks 上使用 JSON 字串數據。 對於剛接觸 Azure Databricks 的使用者,在儲存需要因應變更中或未知結構描述的彈性之半結構化資料時,應優先使用 variant,而非 JSON 字串。 請參閱 模型半結構化數據。

在 Databricks Runtime 15.3 和更新版本中,您可以使用 Variant 數據類型來編碼和查詢半結構化數據。 Databricks 建議 Variant 作為使用 JSON 字串儲存半結構化數據的替代專案。 Variant的改善讀取和寫入效能可讓它取代原生 Spark 複雜類型,例如結構與陣列在某些使用案例中。

如何查詢變體數據?

Variant 數據會使用相同的運算元來查詢欄位、子欄位和陣列元素。

若要查詢欄位,請使用 :。 例如: column_name:field_name 。

若要查詢子欄位,請使用 .。 例如: column_name:field_name.subfield_name 。

若要查詢陣列元素,請使用 [n],其中 n 是該元素的整數索引值。 例如,若要查詢陣列中的第一個值, column_name:array_name[0]。

從 JSON 字串升級為 variant 時,下列差異可能會中斷現有的查詢:

  • 所有變體路徑元素都會以區分大小寫的方式比對。 JSON 字串不區分大小寫。 這表示對於 variant,column_name:FIELD_NAME 和 column_name:field_name 會在已儲存的資料中尋找不同的欄位。
  • [*] 語法不支援用於識別或解構陣列中的所有元素。
  • Variant 會以與 JSON 字串不同的方式編碼 NULL 值。 請參閱 Variant Null 規則。
  • Variant 列對於某些操作有限制。 請參閱 限制。

將 JSON 字串與 variant 相互轉換

在 Databricks Runtime 15.3 和更新版本中,函 to_json 式有額外的功能,可將類型轉換成 VARIANT JSON 字串。 轉換成 VARIANT JSON 字串時會忽略選項。 請參閱 to_json。

這個 parse_json 函式(SQL 或 Python)會將 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()

parse_json若 JSON 字串格式錯誤、超過變體大小限制或無效,函式會回傳錯誤。 當解析錯誤發生時,可以使用try_parse_json函式(SQL 或 Python)來改為回傳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 字串函式,以及行為差異的附註。

Variant 處理轉換的方式 NULL與 JSON 字串不同。 請參閱 Variant 類型轉換規則 和 Variant Null 規則。

注意

若要搭配 PySpark DataFrame 使用這些函式,請從 匯入 pyspark.sql.functions它們。

變體函式 JSON 字串函式 備註
variant_get 轉換 和 get_json_object 採用表達式、路徑和類型。 遵循變體路徑、型別轉換和 null 值的所有規則。
try_variant_get try_cast 和 get_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 爆炸 輸出 pos、key 和 value 欄。 當爆炸陣列時,輸出索引鍵一律為 Null。
variant_explode_outer explode_outer 輸出 pos、key 和 value 欄。 當爆炸陣列時,輸出索引鍵一律為 Null。