【发布时间】:2017-06-12 04:22:31
【问题描述】:
关于我的一个更大的问题,我遇到了两个小问题:我想每天读取一次 JSON 数据并将其保存为 Parquet 以供以后与数据相关的工作。使用镶木地板要快得多。但是我遇到的问题是,在读取该 parquet 时,Spark 总是尝试从模式文件中获取模式,或者只是从第一个 parquet 文件中获取模式,并假定所有文件的模式都是相同的。但有些情况下,我们在某些列中几天没有任何数据。
假设我有一个 JSON 文件,其中的数据具有以下架构:
root
|-- Id: long (nullable = true)
|-- People: array (nullable = true)
| |-- element: struct (containsNull = true)
| | |-- Name: string (nullable = true)
| | |-- Amount: double (nullable = true)
然后我有另一个 JSON 文件,其中没有“人员”列的数据。因此架构如下:
root
|-- Id: long (nullable = true)
|-- People: array (nullable = true)
| |-- element: string (containsNull = true)
当我将它们与read.json 一起读入时,Spark 会遍历所有文件并从中推断出合并的架构,更具体地说是从第一个文件中推断出合并的架构,然后将第二个文件中的行留空,但架构是正确。
但是当我分别阅读这些内容并分别写入 parquet 时,我无法将它们一起阅读,因为对于 Parquet,架构不匹配并且我收到错误消息。
我的第一个想法是读取缺少数据的文件并通过强制转换列类型以匹配第一个模式来手动更改其模式,但是这种手动转换是错误的,它可能不同步,我什至不知道如何将此字符串类型转换为数组或结构类型。
另一个问题是当“金额”字段只有完整的整数时,Spark 会根据需要将它们读取为 longs 而不是 doubles。但如果我使用:
val df2 = df.withColumn("People.Amount", col("People.Amount").cast(org.apache.spark.sql.types.ArrayType(org.apache.spark.sql.types.DoubleType,true)))
那么它并没有改变原来列的类型,而是增加了一个名为People.Amount的新列
【问题讨论】:
标签: json scala apache-spark spark-dataframe parquet