访问空数组或空数组时出现Spark错误

时间:2017-05-21 08:17:33

标签: java json scala apache-spark

我有一个带有这种模式的JSON文件:

{
 "name" : "john doe",
 "phone-numbers" : {
   "home": ["1111", "222"],
   "country" : "England" 
  }
}

家庭电话号码阵列有时可能是空的。

我的spark应用程序收到这些JSONS的列表并执行此操作:

val dataframe = spark.read.json(filePaths: _*)
val result = dataframe.select($"name", 
                               explode(dataframe.col("phone-numbers.home")))

当家庭'数组为空,当我尝试爆炸时收到以下错误:

  

org.apache.spark.sql.AnalysisException:无法解决   ' phone-numbers ['家']'由于数据类型不匹配:参数2   但是,需要整体类型,'''''是字符串类型。;;

如果这个字段是空的还是空的,是否有一种优雅的方法来防止火花爆炸?

2 个答案:

答案 0 :(得分:2)

在spark中有一个名为DataFrameNaFunctions的类,该类专门用于处理DataFrame中的缺失数据。

此类包含三个基本方法:dropreplacefill

要使用此方法,您唯一需要做的就是调用df.na方法,为DataFrameNaFunctions返回df,然后应用返回您的三种方法之一df具有指定的操作。

要解决您的问题,您可以使用类似的内容:

val dataframe = spark.read.json(filePaths: _*)
val result = dataframe.na.drop().select("name", 
                           explode(dataframe.col("phone-numbers.home")))

希望这个帮助,最好的问候

答案 1 :(得分:2)

问题不是空数组("home" : []),而是空数("home" : null)不能与explode

一起使用的数组

所以要先过滤掉空值:

val result = df
   .filter($"phone-numbers.home".isNotNull)
   .select($"name", explode($"phone-numbers.home"))

或用空数组替换空值(我更喜欢你的情况):

val nullToEmptyArr = udf(
   (arr:Array[Long]) => if(arr==null) Array.empty[Long] else arr
)

val result = df
  .withColumn("phone-numbers.home",nullToEmptyArr($"phone-numbers.home")) // clean existing column
  .select($"name", explode($"phone-numbers.home"))