使用spark sql将Json WrappedArray转换为String

时间:2017-07-30 04:18:35

标签: scala apache-spark apache-zeppelin

我正在使用zeppelin笔记本并尝试使用sql从表中加载数据。 在表中,每行有一列是JSON blob。例如,[{'timestamp':12345,'value':10},{'timestamp':12346,'value':11},{'timestamp':12347,'value':12}]

我想选择JSON blob作为字符串,就像原始字符串一样。但是火花自动加载为WrappedArray。

似乎我必须编写一个UDF来将WrappedArray转换为字符串。以下是我的代码。

我首先定义一个Scala函数,然后注册该函数。然后使用列上的注册函数。

val unwraparr = udf ((x: WrappedArray[(Int, Int)]) => x.map { case Row(val1: String) =>  + "," + val2 })
sqlContext.udf.register("fwa", unwraparr)

它不起作用。如果有人能提供帮助我真的很感激。

以下是我正在研究的部分的架构。将有许多amount和timeStamp对。

-- targetColumn: array (nullable = true)
    |-- element: struct (containsNull = true)
    |    |-- value: long (nullable = true)
    |    |-- timeStamp: string (nullable = true)

更新: 我想出了以下代码:

val f = (x: Seq[Row]) => x.map { case Row(val1: Long, val2: String) => x.mkString("+") }

我需要它将objects / struct / row(不确定如何调用struct)连接到单个字符串。

1 个答案:

答案 0 :(得分:1)

如果您在dataframe中加载的数据dataset / spark如下所示schema

+------------------------------------+
|targetColumn                        |
+------------------------------------+
|[[12345,10], [12346,11], [12347,12]]|
|[[12345,10], [12346,11], [12347,12]]|
+------------------------------------+

root
 |-- targetColumn: array (nullable = true)
 |    |-- element: struct (containsNull = true)
 |    |    |-- timeStamp: string (nullable = true)
 |    |    |-- value: long (nullable = true)

然后,您可以将dataframe写为json到临时json文件并将其作为文本文件读取并解析String line并将其转换为dataframe,如下所示( /home/testing/test.json是临时json文件位置)

df.write.mode(SaveMode.Overwrite).json("/home/testing/test.json")

val data = sc.textFile("/home/testing/test.json")

val rowRdd = data.map(jsonLine => Row(jsonLine.split(":\\[")(1).replace("]}", "")))
val stringDF = sqlContext.createDataFrame(rowRdd, StructType(Array(StructField("targetColumn", StringType, true))))

应该让您关注dataframeschema

+--------------------------------------------------------------------------------------------------+
|targetColumn                                                                                      |
+--------------------------------------------------------------------------------------------------+
|{"timeStamp":"12345","value":10},{"timeStamp":"12346","value":11},{"timeStamp":"12347","value":12}|
|{"timeStamp":"12345","value":10},{"timeStamp":"12346","value":11},{"timeStamp":"12347","value":12}|
+--------------------------------------------------------------------------------------------------+

root
 |-- targetColumn: string (nullable = true)

我希望答案很有帮助

最初读作文字而不是数据框

您可以使用我的第二阶段答案,即从json文件读取并解析,进入获取数据帧的第一阶段。