5 struct scala apache-spark apache-spark-sql
我对 Apache Spark 还很陌生,有时仍然遇到困难。我正在尝试导入一个相当复杂的 JSON 文件并将其展平,然后再将其保存到镶木地板文件中。
我的 JSON 文件是一个商店树。
{
"id": "store02",
"name": "store name",
"domain": "domain",
"currency": "EUR",
"address1": "Somewhere",
"country": "GER",
"city": "Berlin",
"zipCode": "12345",
"timeZone": "CET",
"accounts" : [
{
"field1": "",
"filed2": "",
"field3": "",
"optionnalArray1": [
{
"field1": "",
"field2": ""
}
],
"optionnalArray2": ["aa", "bb"]
}
],
"stores": [ .... ]
}
Run Code Online (Sandbox Code Playgroud)
每个商店都可以有一个字段,该字段是帐户数组。帐户有 3 个必填字段和两个可选字段。所以我有一个数据框,其中的字段可以有 3 种不同的类型。
将文件导入数据框中没什么大不了的,但在展平过程中,我可能想对两个数据框进行联合,其帐户可能具有不同的架构,当然我有以下错误:
“只能在具有兼容列类型的表上执行联合”
有没有办法轻松做到这一点?Spark如何毫无问题地导入这样的JSON文件?
假设我有两个数据框。第一个是没有帐户的商店的数据框。第二个是具有帐户的商店的数据框。帐户是一个定义如下的结构体:
val acquirerStruct = StructType(
StructField("merchantId", StringType, nullable = true) ::
StructField("name", StringType, nullable = true) ::
Nil)
val accountStruct = StructType(
StructField("acquirers", ArrayType(acquirerStruct), nullable = true) ::
StructField("applicationCode", StringType, nullable = true) ::
StructField("channelType", StringType, nullable = true) ::
StructField("id", StringType, nullable = true) ::
StructField("terminals", ArrayType(StringType), nullable = true) ::
Nil)
Run Code Online (Sandbox Code Playgroud)
当我想合并两个数据帧时,我之前为第一个数据帧创建了一个列帐户:
df1.withColumn("account", array(lit(null).cast(accountStruct))).union(df2)
Run Code Online (Sandbox Code Playgroud)
如果在 df2 中,所有行都有一个与 accountStruct 具有相同结构的帐户,则它可以正常工作。但事实并非总是如此。帐户可能没有终端或收单机构。这在 JSON 中是完全有效的。在这种情况下,我会遇到前面提到的错误。
“只能在具有兼容列类型的表上执行联合”
我在 PySpark 中遇到了同样的问题,我通过在读取不兼容的数据帧时提供架构来解决它
import copy
...
schema_to_read = copy.deepcopy(df1.schema)
df2 = sql_context.read.format("json").schema(schema_to_read).load(path)
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
2892 次 |
| 最近记录: |