我必须根据Map[String, Object]
的值(而不是键)来确定模式。
示例地图:
val myMap = Map("k1" -> 1, "k2" -> "", "k3"-> new Timestamp(new Date().getTime), "k4" -> 2.0 )
目前,我已通过如下所示的键创建了架构:
// I have created a schema using keys
val schema = StructType(myMap.keys.toSeq.map {
StructField(_, StringType) // StringType is wrong since Object in the Map can be of any datatype
}
// I have created a RDD like below
val rdd = sc.parallelize(Seq(Row.fromSeq(myMap.values.toSeq)))
val df = sc.createDataFrame(rdd,schema)
但是现在我的问题是对象可以是double或date或timestamp或其他任何东西。但是我如上所述使用StringType
创建了一个模式,这是错误的。
有没有从作为对象的Map值创建模式的想法?
答案 0 :(得分:2)
参考文献:这是来自spark code的Encoder
的dataTypeFor的想法
您可以像这样创建结构
ScalaReflection
下面是调用上面的函数的示例代码段。
import org.apache.spark.sql.SparkSession
import org.apache.spark.sql.types.{StringType, StructField, StructType}
/**
*createStruct based on datatype
* @param myObject Object
* @return [[DataType]]
*/
def createStruct(myObject: Object): DataType = {
myObject match {
case t if t.isInstanceOf[String] => StringType
case t if t.isInstanceOf[Long] => LongType
case t if t.isInstanceOf[Integer] => IntegerType
case t if t.isInstanceOf[Float] => FloatType
case t if t.isInstanceOf[Double] => DoubleType
case t if t.isInstanceOf[java.sql.Timestamp] => TimestampType
}
}