變體與 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_NAMEcolumn_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 函式(SQLPython)會將 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函式(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 字串函式,以及行為差異的附註。

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

注意

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

變體函式 JSON 字串函式 備註
variant_get 轉換get_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 爆炸 輸出 poskeyvalue 欄。 當爆炸陣列時,輸出索引鍵一律為 Null。
variant_explode_outer explode_outer 輸出 poskeyvalue 欄。 當爆炸陣列時,輸出索引鍵一律為 Null。