2017-07-25 287 views
0

我的目標是將DataFrame轉換爲JSONObject的有效JSONArray。如何將Spark Dataframe轉換爲JSONObject

我目前使用:

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\"}"] 

我正在尋找一個將這些字符串轉換爲實際的JSONObjects的方法,我找到了一些解決方案,建議find and replace characters,但我正在尋找更乾淨的東西。

我試圖使用org.json庫將每個字符串轉換爲JSONObject,但顯然它不是一個可序列化的對象。

有什麼建議嗎?任何可以工作的快速Scala JSON庫?

或者一般情況下它是如何使用toJSON方法的。

更新

這是有點浪費,但這種做法對我的作品:

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

由於JSONObject的不可序列化 - 我可以用它的toString得到有效的JSON格式。

如果您仍然對我如何改善它有任何建議 - 請讓我知道。

+0

您可以使用您的數據框的示例數據進行更新嗎? –

+0

當我使用'toJSON'時,我不會看到這些引號。我正在使用Spark 1.6。 – philantrovert

+0

@philantrovert,這很奇怪,我們使用Spark 1.6.1。我在網上看到的關於這個問題的所有問題都表明格式是一樣的。 – LiranBo

回答

0

你可以使用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] 
+0

我也考慮過使用大小寫類的選項,但有80多個嵌套字段。所以創建一個相當複雜。我希望以某種方式使用數據框架。 – LiranBo

+0

如果你只是想從JSON中獲取一些數據,你只需要爲你需要的位定義case class hierarchy。例如上面的例子可以用於case class Data(url:String,subnet:String)'。 – jamborta

+0

是的,我知道,但我幾乎需要整個結構。我在一些內部UDF中使用case類來處理一些數據。但結果應該包括幾乎所有的東西。 – LiranBo

0

可以使用DataframeWriter類。

df.write.json(path) 

如果輸出文件有多個記錄/分區,這可能會創建多個零件文件。然後,您可以編寫一個簡單的合併實用程序來合併hdfs /本地文件系統中的部分文件。

在的情況下,輸出是一個小文件 - 你可以使用COALESCE()

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

然後,您可以讀它放回一個DF。

+0

感謝您的建議,但性能是一個嚴重的問題。我無法將數據寫入文件,而是再次讀取它們。 – LiranBo

相關問題