隐含在 Spark Scala 程序中不起作用

Implicits in a Spark Scala program not working

我无法在 Scala 程序中执行从 RDD 到 Dataframe 的隐式转换,尽管我正在导入 spark.implicits._

如有任何帮助,我们将不胜感激。

带有隐式的主程序:

object spark1 {

  def main(args: Array[String]) {
    val spark = SparkSession.builder().appName("e1").config("o1", "sv").getOrCreate()

    import spark.implicits._

    val conf = new SparkConf().setMaster("local").setAppName("My App")
    val sc = spark.sparkContext
    val data = sc.textFile("/TestDataB.txt")
    val allSplit = data.map(line => line.split(","))
    case class CC1(LAT: Double, LONG: Double)
    val allData = allSplit.map( p => CC1( p(0).trim.toDouble, p(1).trim.toDouble))
    val allDF = allData.toDF()
    // ... other code
  }

}

错误如下:

Error:(40, 25) value toDF is not a member of org.apache.spark.rdd.RDD[CC1] val allDF = allData.toDF()

我认为 toDFsqlContext.implicits._ 中,所以您需要导入它而不是 spark.implicits._。至少在 spark 1.6

中是这样

当你在main方法中定义case class CC1 时,你点击了https://issues.scala-lang.org/browse/SI-6649toDF() 然后无法在编译时为那个 class 找到适当的隐式 TypeTag

您可以在这个简单的示例中看到这一点:

case class Out()

object TestImplicits {

  def main(args: Array[String]) {
    case class In()
    val typeTagOut = implicitly[TypeTag[Out]] // compiles
    val typeTagIn = implicitly[TypeTag[In]]   // does not compile: Error:(23, 31) No TypeTag available for In
  }

}

Spark 的相关隐式转换具有此类型参数:[T <: Product : TypeTag](请参见newProductEncoder here),这意味着需要隐式 TypeTag[CC1]

要解决此问题 - 只需将 CC1 的定义移出方法,或完全移出对象:

case class CC1(LAT: Double, LONG: Double)

object spark1 {

  def main(args: Array[String]) {
    val spark = SparkSession.builder().appName("e1").config("o1", "sv").getOrCreate()

    import spark.implicits._

    val data = spark.sparkContext.textFile("/TestDataB.txt")
    val allSplit = data.map(line => line.split(","))

    val allData = allSplit.map( p => CC1( p(0).trim.toDouble, p(1).trim.toDouble))
    val allDF = allData.toDF()
    // ... other code
  }

}