我正在使用scala將json數據讀入spark數據框。 架構如下:使用scala從spark中的數組中抽取結構值
root
|-- metadata: array (nullable = true)
| |-- element: struct (containsNull = true)
| | |-- playerId: string (nullable = true)
| | |-- sources: array (nullable = true)
| | | |-- element: struct (containsNull = true)
| | | | |-- matchId: long (nullable = true)
的數據如下所示:
{ "metadata" : [ { "playerId" : "1234", "sources" : [ { "matchId": 1 } ] }, { "playerId": "1235", "sources": [ { "matchId": 1 } ] } ] }
{ "metadata" : [ { "playerId" : "1234", "sources" : [ { "matchId": 2 } ] }, { "playerId": "1248", "sources": [ { "score": 12.2 , "matchId": 1 } ] } ] }
{ "metadata" : [ { "playerId" : "1234", "sources" : [ { "matchId": 3 } ] }, { "playerId": "1248", "sources": [ { "matchId": 3 } ] } ] }
的目標是找出是否playerId是1234和matchId爲1,則返回isPlayed爲真。來源的結構不固定。可能有其他字段不是matchId。
我寫了一個UDF考慮對象元數據類型WrappedArray [字符串]和我能夠讀取playerId列
def hasPlayer = udf((metadata: WrappedArray[String], playerId: String) => {
metadata.contains(playerId)
})
df.withColumn("hasPlayer", hasPlayer(col("metadata"), col("superPlayerId")))
但我無法弄清楚如何查詢給出playerId的matchId領域。我嘗試將該字段作爲WrappedArray [WrappedArray [Long]]讀取,但它在metadata.sources.matchId列的withColumn中提供了類型轉換異常。
我對Spark比較新。任何幫助將深表感謝。
乾杯!
嘿謝謝你的答案。這會是一個代價高昂的操作嗎?還有一種方法可以保留行數。爆炸我認爲會乘以陣列1中爆炸元素的數量*陣列2中爆炸元素的數量。將這個數據與原始表格連接起來效率高嗎? –
它使用了所有更高級別的Spark功能,這是儘可能讓Catalyst優化事情的一種方法。但是,你爲什麼不試試看它是否「高效」? – Vidya