Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/apache-spark/5.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 基于不同案例类创建数据集_Scala_Apache Spark_Pattern Matching_Case Class - Fatal编程技术网

Scala 基于不同案例类创建数据集

Scala 基于不同案例类创建数据集,scala,apache-spark,pattern-matching,case-class,Scala,Apache Spark,Pattern Matching,Case Class,嗨,我有一个RDD,它基本上是在读取CSV文件后生成的。 我定义了一个方法,它基本上根据输入参数将rdd的行映射到不同的案例类 返回的RDD需要转换为数据帧 当我尝试运行相同的程序时,我得到以下错误 定义的方法是 case class Australiafile1(sectionName: String, profitCentre: String, valueAgainst: String, Status: String) case class Australiafile2(secti

嗨,我有一个RDD,它基本上是在读取CSV文件后生成的。 我定义了一个方法,它基本上根据输入参数将rdd的行映射到不同的案例类

返回的RDD需要转换为数据帧 当我尝试运行相同的程序时,我得到以下错误

定义的方法是

  case class Australiafile1(sectionName: String, profitCentre: String, valueAgainst: String, Status: String)

  case class Australiafile2(sectionName: String, profitCentre: String)

  case class defaultclass(error: String)

  def mapper(line: String, recordLayoutClassToBeUsed: String) = {

    val fields = line.split(",")
    var outclass = recordLayoutClassToBeUsed match {
      case ("Australiafile1") => Australiafile1(fields(0), fields(1), fields(2), fields(3))
      case ("Australiafile2") => Australiafile2(fields(0), fields(1))
    }
    outclass

  }
方法的输出用于创建数据帧,如下所示

      val inputlines = spark.sparkContext.textFile(inputFile).cache().mapPartitionsWithIndex { (idx, lines) => if (idx == 0) lines.drop(numberOfLinesToBeRemoved.toInt) else lines }.cache()
      val records = inputlines.filter(x => !x.isEmpty).filter(x => x.split(",").length > 0).map(lines => mapper(lines, recordLayoutClassToBeUsed))

      import spark.implicits._

      val recordsDS = records.toDF()
      recordsDS.createTempView("recordtable")
      val output = spark.sql("select * from recordtable").toDF()
      output.write.option("delimiter", "|").option("header", "false").mode("overwrite").csv(outputFile)
收到的错误如下所示

线程“main”java.lang.NoClassDefFoundError中出现异常:未找到与可序列化的产品对应的java类 位于scala.reflect.runtime.JavaMirrors$JavaMirror.typeToJavaClass(JavaMirrors.scala:1300) 位于scala.reflect.runtime.JavaMirrors$JavaMirror.runtimeClass(JavaMirrors.scala:192) 位于scala.reflect.runtime.JavaMirrors$JavaMirror.runtimeClass(JavaMirrors.scala:54) 位于org.apache.spark.sql.catalyst.encoders.ExpressionEncoder$.apply(ExpressionEncoder.scala:60) 位于org.apache.spark.sql.Encoders$.product(Encoders.scala:275) 在org.apache.spark.sql.LowPrioritySQLImplicits$class.newProductEncoder上(SQLImplicits.scala:233) 位于org.apache.spark.sql.SQLImplicits.newProductEncoder(SQLImplicits.scala:33)

您能告诉我这有什么问题吗?我如何克服这一问题?

试试:

trait AustraliaFile extends Serializable

case class Australiafile1(sectionName: String, profitCentre: String, valueAgainst: String, Status: String) extends AustraliaFile

case class Australiafile2(sectionName: String, profitCentre: String) extends AustraliaFile
您的类不是可序列化的,但是Spark只能编写可序列化的对象。另外,将相关类基于一个共同的祖先总是一个好主意,这样您就可以将RDD声明为
RDD[AustraliaFile]
而不是
RDD[Any]

此外,您的类匹配逻辑可以简化为

def mapper(line: String, recordLayoutClassToBeUsed: String) = {
  val fields = line.split(",")
  recordLayoutClassToBeUsed match {
     case ("Australiafile1") => Australiafile1(fields(0), fields(1), fields(2), fields(3))
    case ("Australiafile2") => Australiafile2(fields(0), fields(1))
  }
}

case类应该在主类之外编写——它们只在主方法之外。此外,如果我只从映射器方法返回一个case类对象,而不匹配和检查条件,则不会出现错误