Map [String,java.lang.Object]到DataFrame模式问题

时间:2018-11-05 23:00:50

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

我必须根据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值创建模式的想法?

1 个答案:

答案 0 :(得分:2)

参考文献:这是来自spark codeEncoder的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
    }
  }