使用Spark StructType支持嵌套结构

时间:2016-10-06 11:29:28

标签: scala apache-spark dataframe apache-spark-sql

Spark的StructType#add方法的javadocs显示第二个参数需要是一个扩展DataType的类。

我有一种情况需要在MapType上添加一个相当复杂的StructType作为字段。

具体来说,这个MapType字段是几个嵌套结构的映射:

Map<String,Map<Integer,Map<String,String>>>

因此它是一个带有2个嵌套/内部地图的地图。类型为Map<String,String>的最里面的地图(所以在Spark的说法中,MapType[StringType,StringType])。

中间地图的类型为Map<Integer,Map<String,String>>(所以在Spark的用语中再次提到MapType[IntegerType,MapType[StringType,StringType]])。

如何在调用StructType#add方法时指定这种复杂的嵌套地图结构?

也就是说,我希望能够做到这样的事情:

var myStruct : StructType = new StructType()
myStruct.add("complex-o-map",
    MapType[StringType,MapType[IntegerType,MapType[StringType,StringType]]])

然而,看起来我只能添加单个最外层的MapType

var myStruct : StructType = new StructType()
myStruct.add("complex-o-map", MapType)

这让我感到难过。如何在调用add(...)期间指定嵌套的地图结构?

1 个答案:

答案 0 :(得分:2)

MapType(.eg StringTypesMapType)所期望的“类型”在Scala意义上并不是真正的类型,它们是对象,所以你应该将它们作为构造函数参数而不是类型参数传递 - 换句话说,使用()而不是[]

val myStruct = new StructType().add("complex-o-map",
  MapType(StringType,MapType(IntegerType,MapType(StringType,StringType))))

myStruct.printTreeString()
// prints:
// root
// |-- complex-o-map: map (nullable = true)
// |    |-- key: string
// |    |-- value: map (valueContainsNull = true)
// |    |    |-- key: integer
// |    |    |-- value: map (valueContainsNull = true)
// |    |    |    |-- key: string
// |    |    |    |-- value: string (valueContainsNull = true)