2017-05-25 91 views
1

當我在數據框的字符串列中尋找解析json的方法時,我一直運行到更簡單地讀取json文件源的結果中。我的源代碼實際上是一個配置單元ORC表,其中一列是json格式的一些字符串。我真的很想把它轉換成像地圖一樣解析的東西。在Spark數據框列中處理json字符串

我無法找到一個方法來做到這一點:

import java.util.Date 
import org.apache.spark.sql.Row 
import scala.util.parsing.json.JSON 

val items = sql("select * from db.items limit 10") 
//items.printSchema 
val internal = items.map { 
    case Row(externalid: Long, itemid: Long, locale: String, 
      internalitem: String, version: Long, 
      createdat: Date, modifiedat: Date) 
     => JSON.parseFull(internalitem) 
} 

我想這應該工作,但也許有這樣做的,而不是因爲我碰到下面的錯誤更星火方式:

java.lang.ClassNotFoundException: scala.Any 
at scala.reflect.internal.util.AbstractFileClassLoader.findClass(AbstractFileClassLoader.scala:62) 

具體來說,我的輸入數據看起來大約是這樣的:

externalid, itemid, locale, internalitem, version, createdat, modifiedat 
     123, 321, "en_us", "{'name':'thing','attr':{ 
           21:{'attrname':'size','attrval':'big'}, 
           42:{'attrname':'color','attrval':'red'} 
           }}",    1, 2017-05-05…, 2017-05-06… 

是的,它完全不是RFC 7158。

attr鍵可以在5到任意80000個值的30,所以我希望得到這樣的事情,而不是:

externalid, itemid, locale, internalitem, version, createdat, modifiedat 
     123, 321, "en_us", "{"name':"thing","attr":[ 
           {"id":21,"attrname':"size","attrval":"big"}, 
           {"id":42,"attrname":"color","attrval":"red"} 
           ]}",    1, 2017-05-05…, 2017-05-06… 

然後拼合internalitem到字段和爆炸attr陣列:

externalid, itemid, locale, name, attrid, attrname attrval, version, createdat, modifiedat 
     123, 321, "en_us", "thing", 21, "size", "big",  1, 2017-05-05…, 2017-05-06… 
     123, 321, "en_us", "thing", 21, "color", "red",  1, 2017-05-05…, 2017-05-06… 
+0

此代碼通過解析源數據框中的數據字段來創建新的數據幀。 'spark.sqlContext.read.json(df.select(「col1」)。rdd.map(_。getAs [String](0)))' –

+0

@ rogue-one是的,所以當你這樣做時你不再可以參考json解析後的其他列,對嗎? EG如果我扁平了json中的內容,並希望將所有列與新列一起輸出,那麼這將如何完成? – dlamblin

+0

你看過這個:https://stackoverflow.com/questions/35068792/sp​​ark-1-4-1-dataframe-explode-list-of-json-objects - 我認爲爆炸方法應該可以幫助你做到那。當然 - 當你來自獸人時,它可能行不通。這可以幫助你提取JSON https://stackoverflow.com/questions/34069282/how-to-query-json-data-column-using-spark-dataframes –

回答

2

我從來沒有使用這樣的計算,但我有一個建議給你:

在做之前做任何操作在你自己的列上,只需檢查sql.functions包,其中包含一大堆有用的函數,用於處理日期提取和格式化,字符串連接和分離等列,還提供了幾個函數來處理json對象,如:from_jsonjson_tuple

使用那些你只需要導入他們,稱他們爲選擇方法像這裏面的方法:

import spark.implicits._ 
import org.apache.spark.sql.functions._ 
val transofrmedDf = df.select($"externalid", $"itemid", … from_json($"internalitem", schema), $"version" …) 

首先你必須創建一個模式爲您的JSON列,並把它放在schema變量

希望它有幫助。

+0

謝謝。所以如果我寫出transofrmedDf它將包含根據模式解析的json。但不是其他專欄。我有點新的Spark DataFrame,是否可以這樣說:'df.select($「externalid」,$「itemid」,... from_json($「internalitem」,schema),$「version」...) '? – dlamblin

+0

@dlamblin當然,這顯然是可能的! –

+0

好的,回答主要的最初問題。接下來的部分是將json中的內容映射到「想獲得類似內容」或「展開...展開」視圖。我想我會提出一個單獨的問題。 https://stackoverflow.com/q/44192994/459 – dlamblin