Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/scala/19.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Scala 2.11及;Spark 2.0.0动态创建案例类对数据集进行编码_Scala_Apache Spark - Fatal编程技术网

Scala 2.11及;Spark 2.0.0动态创建案例类对数据集进行编码

Scala 2.11及;Spark 2.0.0动态创建案例类对数据集进行编码,scala,apache-spark,Scala,Apache Spark,我正在尝试将我的应用程序从Spark 1.6.2更新到2.0.0,我的问题是从Dataframe(我读过的拼花地板)创建一个数据集 我知道我可以使用case类或tuple来键入Dataframe,然后拥有一个数据集,但在运行之前,我不知道将加载哪些数据给用户,所以列的类型和数量是多少 要加载数据,我使用SparkSession从拼花地板读取数据,如下所示: spark.read.schema(schema).parquet(dataPath) schemaOfData是一个StructType

我正在尝试将我的应用程序从Spark 1.6.2更新到2.0.0,我的问题是从Dataframe(我读过的拼花地板)创建一个数据集

我知道我可以使用case类或tuple来键入Dataframe,然后拥有一个数据集,但在运行之前,我不知道将加载哪些数据给用户,所以列的类型和数量是多少

要加载数据,我使用SparkSession从拼花地板读取数据,如下所示:

spark.read.schema(schema).parquet(dataPath)
schemaOfData是一个StructType,由一个列表[Map[String,String]]实例化,该列表包含列的名称及其类型(即else String-else-Double)

我在StackOverflow上发现了这一点,但如果没有更简单的方法来解决我的问题,我很难理解它和guest:


感谢您创建从spark数据类型到Scala本机数据类型的隐式转换

然后将该类型映射到具有Spark DataFrame的StructFields的模式

  import org.apache.spark.sql.SparkSession
  import org.apache.spark.sql.types._


    val spark = SparkSession
      .builder
      .appName("Movies Reviews")
      .config("spark.master", "local")
      .getOrCreate()

    import spark.implicits._
    val someDF = Seq(
      (8, "bat"),
      (64, "mouse"),
      (-27, "horse")
    ).toDF("number", "word")

    someDF.printSchema()

    def schemaCaseClass(schema:StructType, className:String)
                       (implicit sparkTypeScala:DataType => String):String = {
      def structField(col:StructField):String = {
        val sparkTypes = sparkTypeScala(col.dataType)
        col match {
          case x if x.nullable => s"  ${col.name}:Option[$sparkTypes]"
          case _ => s"  ${col.name}:$sparkTypes"
        }
      }

    val fieldsName = schema.map(structField).mkString(",\n  ")
    s"""
       |case class $className (
       |  $fieldsName
       |)
    """.stripMargin
    }

    implicit val scalaTypes:DataType => String = {
        case _: ByteType => "Byte"
        case _: ShortType => "Short"
        case _: IntegerType => "Int"
        case _: LongType => "Long"
        case _: FloatType => "Float"
        case _: DoubleType => "Double"
        case _: DecimalType => "java.math.BigDecimal"
        case _: StringType => "String"
        case _: BinaryType => "Array[Byte]"
        case _: BooleanType => "Boolean"
        case _: TimestampType => "java.sql.Timestamp"
        case _: DateType => "java.sql.Date"
        case _: ArrayType => "scala.collection.Seq"
        case _: MapType => "scala.collection.Map"
        case _: StructType => "org.apache.spark.sql.Row"
        case _ => "String"
    }


    println(schemaCaseClass(someDF.schema, "someDF"))

据我所知,性能应该优于使用map,而不改变我应用程序中的所有遗留代码,请检查:在Scala中编码类型通用逻辑需要在运行时获得某种类型的代码,这可能非常麻烦。Spark使用表达式对此进行旁路,为列类型启用类似SQL的行为(因此在运行时进行检查)。这就是为什么您可能希望利用DataFrames的类型泛型性或Row的灵活性来处理它,而不是自己做任何事情。或者?请解释一下你的答案