我正在使用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