我有一个案例类,我想在Spark中转换为架构
case class test(request1:Map[String, Any],response1:Option[String] = None,)
如何将此类转换为架构对象
val mySchema = StructType(
StructField("request1", Map[String, Any], false),StructField(" response1", Option[String],true))
MapType和选项在DataType
中不可用答案 0 :(得分:7)
无法使用此案例类创建DataFrame
架构。虽然Spark支持地图MapType
和Options
使用包裹类型处理Nones
已转换为NULLs
,但不支持Any
类型的架构。
假设您将Value
类型更改为String
:
case class Test(request1: Map[String, String], response1: Option[String] = None)
相应的模式应如下所示:
StructType(Seq(
StructField("request1", MapType(StringType, StringType, true), true),
StructField("response1", StringType, true)
))
答案 1 :(得分:1)
正如@ zero323已经雄辩地说,即使你可以使用MapType
,在你的情况下它可能不是最好的。您的请求和响应可能已经过结构化,您应该投入一些时间来定义该结构/模式。例如,您可以以编程方式一次定义所有字符串类型列,所有int类型列都以编程方式定义,如下面的代码所示。
在sql中,Option
转换为可以为空的StructField
的第三个参数,它是真或假 - 大多数时候你将它设置为true,因此允许空值。
您可以像这样定义嵌套结构:
import org.apache.spark.sql.types._
case class Request(url:String, enc:String)
case class Response(code:Int, body:String)
case class Record( request:Request, response:Response)
val names = Array("url", "enc")
val requestStructType = StructType( names.map( name => StructField(name, StringType, true)))
/// example of StructType with differing types, programmaticaly, add more field names if needed
val respNamesInt = Array("code")
val respNamesString = Array("body")
val responseStructType =
StructType( respNamesInt.map( name => StructField(name, IntegerType, true)) ++
respNamesString.map( name => StructField(name, StringType, true)))
// example of nested structures
val recordStructType =
StructType( Array(StructField("request", requestStructType, false), // nullable = false
StructField("response", responseStructType, true))) // nullable = true