如何在Spark中读取嵌套集合

时间:2015-05-02 22:20:06

标签: hadoop hive apache-spark parquet

我有一张镶木桌子,其中一列是

  

,array< struct< col1,col2,.. colN>>

可以使用LATERAL VIEW语法在Hive中对此表运行查询。

如何将此表读入RDD,更重要的是如何在Spark中过滤,映射等嵌套集合?

在Spark文档中找不到对此的任何引用。提前感谢您的任何信息!

PS。毛毡可能有助于在桌子上给出一些统计数据。  主表~600中的列数。行数~200m。  嵌套集合中的“列”数〜10。平均集合中的平均记录数~35。

3 个答案:

答案 0 :(得分:8)

我会给出一个基于Python的答案,因为我正在使用它。我认为Scala有类似的东西。

根据Python API docs,Spark 1.4.0中添加了explode函数来处理DataFrames中的嵌套数组。

创建测试数据框:

from pyspark.sql import Row

df = sqlContext.createDataFrame([Row(a=1, intlist=[1,2,3]), Row(a=2, intlist=[4,5,6])])
df.show()

## +-+--------------------+
## |a|             intlist|
## +-+--------------------+
## |1|ArrayBuffer(1, 2, 3)|
## |2|ArrayBuffer(4, 5, 6)|
## +-+--------------------+

使用explode展平列表列:

from pyspark.sql.functions import explode

df.select(df.a, explode(df.intlist)).show()

## +-+---+
## |a|_c0|
## +-+---+
## |1|  1|
## |1|  2|
## |1|  3|
## |2|  4|
## |2|  5|
## |2|  6|
## +-+---+

答案 1 :(得分:3)

另一种方法是使用这样的模式匹配:

val rdd: RDD[(String, List[(String, String)]] = dataFrame.map(_.toSeq.toList match { 
  case List(key: String, inners: Seq[Row]) => key -> inners.map(_.toSeq.toList match {
    case List(a:String, b: String) => (a, b)
  }).toList
})

您可以直接在Row上进行模式匹配,但由于某些原因可能会失败。

答案 2 :(得分:1)

以上答案都是很好的答案,并从不同方面解决这个问题; Spark SQL也是访问嵌套数据的非常有用的方法。

以下示例说明如何在SQL中直接使用explode()来查询嵌套集合。

SELECT hholdid, tsp.person_seq_no 
FROM (  SELECT hholdid, explode(tsp_ids) as tsp 
        FROM disc_mrt.unified_fact uf
     )

tsp_ids是一个嵌套的结构体,它有许多属性,包括我在上面的外部查询中选择的person_seq_no。

上面是在Spark 2.0中测试过的。我做了一个小测试,它在Spark 1.6中不起作用。当Spark 2不在时,就会问这个问题,所以这个答案很好地补充了处理嵌套结构的可用选项列表。

在用于SQL访问的explode()上,无法解析JIRA: