我是Spark 2.0的新手,并在我们的代码库中使用数据集。我有点注意到我需要在代码中到处import spark.implicits._
。例如:
File A
class A {
def job(spark: SparkSession) = {
import spark.implcits._
//create dataset ds
val b = new B(spark)
b.doSomething(ds)
doSomething(ds)
}
private def doSomething(ds: Dataset[Foo], spark: SparkSession) = {
import spark.implicits._
ds.map(e => 1)
}
}
File B
class B(spark: SparkSession) {
def doSomething(ds: Dataset[Foo]) = {
import spark.implicits._
ds.map(e => "SomeString")
}
}
我想问的是,是否有更清洁的方法可以做到
ds.map(e => "SomeString")
没有在我执行地图的每个功能中导入implicits?如果我不导入它,我会收到以下错误:
错误:(53,13)无法找到存储在数据集中的类型的编码器。导入spark.implicits.支持原始类型(Int,String等)和产品类型(case类)。将来版本中将添加对序列化其他类型的支持。
答案 0 :(得分:0)
在class
或object
而不是每个函数中进行导入会有所帮助。对于“文件A”和“文件B”示例:
File A
class A {
val spark = SparkSession.builder.getOrCreate()
import spark.implicits._
def job() = {
//create dataset ds
val b = new B(spark)
b.doSomething(ds)
doSomething(ds)
}
private def doSomething(ds: Dataset[Foo]) = {
ds.map(e => 1)
}
}
File B
class B(spark: SparkSession) {
import spark.implicits._
def doSomething(ds: Dataset[Foo]) = {
ds.map(e => "SomeString")
}
}
通过这种方式,您可以获得可管理的imports
。
不幸的是,据我所知,没有其他方法可以进一步减少进口数量。这是因为在执行实际SparkSession
时需要import
对象。因此,这是最好的。
答案 1 :(得分:0)
您可以在每个调用的方法中重用现有的SparkSession。通过在方法内部创建本地val-
val spark: org.apache.spark.sql.SparkSession = org.apache.spark.sql.SparkSession.active
然后
import spark.implicits._
到目前为止,对我来说还不错。