我想使用spark进程将json结构重新格式化为包含对象数组的结构。 我的输入文件包含以下行:
{ "keyvals" : [[1,"a"], [2, "b"]] },
{ "keyvals" : [[3,"c"], [4, "d"]] }
我希望我的流程输出
{ "keyvals": [{"id": 1, "value": "a"}, {"id": 2, "value": "c"}] },
{ "keyvals": [{"id": 3, "value": "c"}, {"id": 4, "value": "d"}] }
最好的方法是什么?
要查看示例输入,您可以在scala spark-shell中运行:
var jsonStrings = Seq("""{"keyvals": [[1,"a"], [2, "b"]] }""", """{ "keyvals" : [[3,"c"], [4, "d"]] }""")
var inputRDD = sc.parallelize(jsonStrings)
var df = spark.sqlContext.read.json(inputRDD)
// reformat goes here ?
df.write.json("myfile.json")
谢谢
答案 0 :(得分:1)
如果您检查架构,您会看到以下结构实际映射到array<array<string>>
df.printSchema
// root
// |-- keyvals: array (nullable = true)
// | |-- element: array (containsNull = true)
// | | |-- element: string (containsNull = true)
除非修复了元素数量,否则您需要udf
:
import org.apache.spark.sql.functions._
case class Record(id: Long, value: String)
val parse = udf((xs: Seq[Seq[String]]) => xs.map {
case Seq(id, value) => Record(id.toLong, value)
})
val result = df.select(parse($"keyvals").alias("keyvals"))
,结果可以转换为toJSON
result.toJSON.toDF("keyvals").show(false)
// +-------------------------------------------------------+
// |keyvals |
// +-------------------------------------------------------+
// |{"keyvals":[{"id":1,"value":"a"},{"id":2,"value":"b"}]}|
// |{"keyvals":[{"id":3,"value":"c"},{"id":4,"value":"d"}]}|
// +-------------------------------------------------------+
或使用JSON编写器(result.write.json
)编写。
也可以使用强类型Dataset
:
df.as[Seq[Seq[String]]].map { xs => xs.map {
case Seq(id, value) => Record(id.toLong, value)
}}.toDF("keyvals")