在spark中读取json时,将单个值转换为数组

时间:2018-02-09 19:55:02

标签: json apache-spark

Json可以将单个值或多个值的数组作为属性值。例如,"A":"ae""A":["ab", "cd"] 当我读取json-nd文件(每行是一个json)时,我的target属性可能只有一个值或一个相同类型值的数组。

我需要使用explode()来获取数据。但是当显示单个值时,explode()会抱怨。

所以,我的问题是如何使某个属性的所有值成为spark数据帧中的数组?

1 个答案:

答案 0 :(得分:1)

如果所有值都是标量,则可以使用array函数:

import org.apache.spark.sql.functions._

array(col("A")).alias("A")

spark.read.json(
  Seq("""{"A": "ae"}""").toDS).select(array(col("A")).alias("A")
).show
// +----+
// |   A|
// +----+
// |[ae]|
// +----+

如果值混合,您可以手动解析事物:

import org.apache.spark.sql.types._

Seq("""{"A": "ae"}""", """{"A": ["ab", "cd"]}""").toDS.select(coalesce(
    // Attempt to parse value as array<string>
    from_json($"value", StructType.fromDDL("A array<string>"))("A"),
    // If the first one fails, try to extract it as string and enclose with array
    array(get_json_object($"value", "$.A"))
).alias("A")).show

// +--------+
// |       A|
// +--------+
// |    [ae]|
// |[ab, cd]|
// +--------+

如果您使用较旧的Spark版本替换:

 StructType.fromDDL("A array<string>")

StructType(Seq(StructField("A", ArrayType(StringType))))