我正在用Scala实现一个模板方法模式。其思想是该方法返回一个Dataset[Metric]。
但是,当我将enrichedMetrics转换为DataSet enrichedMetrics.as[Metric]时,为了将记录映射到指定的类型,我必须使用隐式。这意味着向MetricsProcessor传递一个SparkSession,这对我来说似乎不是最好的解决方案。
我现在看到的解决方案是将spark: SparkSession作为参数传递给模板方法。然后在模板方法中导入spark.implicits._。
在这种情况下,有没有更合适的方式来实现模板方法模式?
trait MetricsProcessor {
// Template method
def parseMetrics(startDate: Date, endDate: Date, metricId: Long): Dataset[Metric] = {
val metricsFromSource: DataFrame = queryMetrics(startDate, endDate)
val enrichedMetrics = enrichMetrics(metricsFromSource, metricId)
enrichedMetrics.as[Metric] <--- //requires spark.implicits
}
// abstract method
def queryMetrics(startDate: Date, endDate: Date): DataFrame
def enrichMetrics(metricsDf: DataFrame, metricId: Long): DataFrame = {
/*Default implementation*/
}
}发布于 2019-07-24 16:08:18
你在这里遗漏了你的类型Metric的Encoder,spark不能隐式地找到,对于像String,Int等常见类型,spark有隐式编码器。
此外,如果源类型和目标类型中的列不相同,则不能对数据框执行简单的.as。我将在这里做一些假设。
对于case class指标
case class Metric( ??? )parseMetrics中的行将更改为,
编码器选项1-显式传递
enrichedMetrics.map(row => Metric( ??? ))(Encoders.product[Metric])编码器选项2-隐式传递
implicit val enc : Encoder[Metric] = Encoders.product[Metric]
enrichedMetrics.map(row => Metric( ??? ))注意,正如其中一个注释所指出的,如果您的parseMetric方法总是返回Dataset[Metric],那么您可以将隐式编码器添加到特征的主体中。
希望这能帮上忙。
https://stackoverflow.com/questions/57162522
复制相似问题