我一直看到,当我们使用map函数时,我们可以使用case类从rdd创建一个数据框,如下所示:-
case class filematches(
row_num:Long,
matches:Long,
non_matches:Long,
non_match_column_desc:Array[String]
)
newrdd1.map(x=> filematches(x._1,x._2,x._3,x._4)).toDF()
这众所周知,效果很好!
我想知道,为什么我们在这里特别需要案例类? 使用带有参数化构造函数的普通类,我们应该能够实现相同的效果(因为它们将是val而不是私有的):-
class filematches1(
val row_num:Long,
val matches:Long,
val non_matches:Long,
val non_match_column_desc:Array[String]
)
newrdd1.map(x=> new filematches1(x._1,x._2,x._3,x._4)).toDF
在这里,我正在使用new关键字实例化该类。
上面的运行给了我错误:-
错误:toDF的值不是org.apache.spark.rdd.RDD [filematches1]的成员
我确定我在这里缺少案例类和常规类的一些关键概念,但是还找不到。
答案 0 :(得分:0)
解决以下错误 值toDF不是org.apache.spark.rdd.RDD [...]的成员 您应该将案例类定义移出使用函数的位置。您可以参考http://community.cloudera.com/t5/Advanced-Analytics-Apache-Spark/Spark-Scala-Error-value-toDF-is-not-a-member-of-org-apache/td-p/29878了解模式的详细信息。
在您的其他查询上-案例类是语法糖,它们提供了以下附加功能
案例类不同于常规类。它们特别用于创建不可变对象。
它们具有默认的apply函数,该函数用作构造函数来创建对象。 (因此,较小的代码)
case类中的所有变量默认为val类型。因此是一成不变的。这对火花世界来说是一件好事,因为所有红色都是不可变的
案例类别的示例是 案例类Book(name:string) val book1 = Book(“ test”)
您无法更改book1.name的值,因为它是不可变的。而且您无需在此处说出新的Book()即可创建对象。
此外,在比较案例类的两个对象时,将比较其结构而不是引用。
Edit:Spark使用以下类来推断模式 代码链接: https://github.com/apache/spark/blob/branch-2.4/sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/ScalaReflection.scala
如果您检查。在schemaFor函数中(第719行到791行)。它将Scala类型转换为催化剂类型。我尚未添加用于处理架构案例推断的非案例类的案例。因此,每次您尝试将非案例类与推断模式一起使用时。转到其他选项,因此给出了不支持$ other类型的模式错误。
希望这会有所帮助