【问题标题】:How to convert Spark Dataframe to JSON using json4s, in Scala?如何在 Scala 中使用 json4s 将 Spark Dataframe 转换为 JSON?
【发布时间】:2022-12-18 19:37:53
【问题描述】:

尝试将数据帧转换为 JSON 字符串,输出只是 {}。不确定我做错了什么?

这只是一个测试,但我需要使用的完整 Dataframe 模式是 800 多列,所以如果可能的话,我不想在代码中专门指定每个字段!代码在锁定的公司环境中运行,因此我无法向系统写入或读取文件,只能输出字符串。

import org.json4s.jackson.Serialization.write
import org.json4s.DefaultFormats

implicit val formats = DefaultFormats

val test = spark.sql("SELECT field1, field2, field3 FROM myTable LIMIT 2");

println("Output:");
write(test);


Output:
res12: String = {}

雪上加霜的是,我可以使用内置的 toJSON 函数(来自 scala.util.parsing.json._),但我们的公司环境已将 spark.sql.jsonGenerator.ignoreNullFields 设置为 True,它无法更改,但输出必须包含空字段——希望 json4s 能够做到:)

谢谢

【问题讨论】:

    标签: scala apache-spark apache-spark-sql json4s


    【解决方案1】:

    不确定我做错了什么?

    这是因为spark.sql(...) 返回一个 DataFrame,而 DataFrame 的所有实例变量都是私有的,因此您的解析器基本上会忽略它们。你可以试试这个:

    case class PrivateStuff(private val thing: String)
    
    write(PrivateStuff("something"))
    // ourputs {}
    

    因此,您不能只将整个 DataFrame 转换为 JSON,您可以做的是收集数据(返回 Array[Row]List[Row])并尝试将每一行转换为 Scala 对象,因为转换的结果行到 JSON 可能不是你想要的,然后使用 write 函数:

    case class YourModel(x1: String, ...)
    object YourModel {
      def fromRow(row: Row): Option[YourModel] = // conversion logic here
    }
    
    val myData: Array[YourModel] = spark.sql("SELECT ...")
      .collect()
      .map(YourModel.fromRow)
      .collect { case Some(value) => value }
    
    write(myData)
    

    【讨论】: