scala 如何将Spark Dataframe 转换为JSONObject

6qfn3psc  于 2022-11-09  发布在  Scala
关注(0)|答案(4)|浏览(260)

我的目标是将DataFrame转换为有效的JSONObject的JSON数组。
我目前正在使用:

val res = df.toJSON.collect()

但我得到的是JSON转义字符串的数组[字符串]数组,即:

["{\"url\":\"http://www.w3schools.com/html/html_form_action.asp?user=123\",\"subnet\":\"32.2.208.1\",\"country\":\"\",\"status_code\":\"200\"}"]

我正在寻找一种将这些字符串转换为实际JSONObject的方法,我找到了一些建议给find and replace characters的解决方案,但我正在寻找更干净的解决方案。
我尝试使用org.json库将每个字符串转换为JSONObject,但显然它不是Serializable对象。
有什么建议吗?有没有可以工作的快速Scala JSON库?
或者通常建议如何使用toJSON方法。

更新

这有点浪费,但这个选项对我很有效:

val res = df.toJSON.map(new JSONObject(_).toString).collect()

因为JSONObject是不可序列化的,所以我可以使用它的toString来获取有效的JSON格式。
如果你还有任何关于我如何改进它的建议-请让我知道。

pxyaymoc

pxyaymoc1#

您可以使用spray-json将字符串解析为案例类:

import spray.json._
import DefaultJsonProtocol._
case class Data(url: String, subnet: String, country: String, status_code: String)
implicit val dataFormat = jsonFormat4(Data)
val source = Array("{\"url\":\"http://www.w3schools.com/html/html_form_action.asp?user=123\",\"subnet\":\"32.2.208.1\",\"country\":\"\",\"status_code\":\"200\"}")
val data = source(0).parseJson.convertTo[Data]
roejwanj

roejwanj2#

您可以使用DataframeWriter类。

df.write.json(path)

如果输出文件具有多个记录/分区,这可能会创建多个零件文件。然后,您可以编写一个简单的合并实用程序来合并HDFS/本地文件系统中的零件文件。
如果输出是一个小文件,您可以使用coalesce()

df.coalesce(1).write.json(path)

然后您可以将其读回到DF中。

lp0sw83n

lp0sw83n3#

你可以:
1.收集数据框-您将获得Array[Row]
1.将折叠它的每一行Map到Map[String,Any]-结果将乘以Array[Map[String,Any]]
1.序列化到JSON

implicit val formats = DefaultFormats

val dataFrame = (1 to 10)
  .map(i => ("value" + i, i))
  .toDF("name", "value")

val maps = dataFrame
  .collect
  .map(
    row => dataFrame
      .columns
      .foldLeft(Map.empty[String, Any])
      (
        (acc, item) => acc + (item -> row.getAs[Any](item))
      )
  )

val json = Serialization.write(maps)

println(json)
noj0wjuj

noj0wjuj4#

I will show how dataframe converted into Json object list in spark.
I/P: Dataframe
O/P Json : [{ "id":"111","Loc":"Pune"},{"id":"2222","Loc":"Mumbai"}]
Sol:-> 
1] Create  Person POJO having id and loc fields.
2] Suppose dataframe named 'myDF'
3] myDF.collect.foreach { record =>
 val recMap = record.getValuesMap(myDF.columns).toMap[Any, Any]
 val person =new Person
 person.setLoc(recMap("LOC"))
 jsonList.append(person) //List of Person obj
}
val gson = new Gson //GSON lib
jsonStr = gson.toJson(jsonList.asJava)

相关问题