【发布时间】:2019-07-23 10:54:36
【问题描述】:
我正在 Scala 中实现模板方法模式。这个想法是该方法返回一个Dataset[Metric]。
但是当我将enrichedMetrics 转换为DataSet enrichedMetrics.as[Metric] 时,我必须使用implicits 来将记录映射到指定的类型。这意味着将 SparkSession 传递给MetricsProcessor,这对我来说似乎不是最好的解决方案。
我现在看到的解决方案是将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*/
}
}
【问题讨论】:
-
实际上你不需要
spark.implicits._,而只是它带来的一个隐含含义,一个Encoder[Metrics]。您可能只要求将其作为方法的隐式参数。此外,如果Metrics是一个具体的案例类,您可以使用org.apache.spark.sql.Encoders.product辅助方法自己创建Encoder。 (我可能有错别字,但我希望这可以帮助你). -
@LuisMiguelMejíaSuárez 你能举个例子吗?
-
如果 Metric 是用户无法指定的类型参数,则
def parseMetrics(...)(implicit encoder: Encoder[Metric]): Dataset[Metric](其中的点是您的常规参数)。 - 如果 Metric 是一个具体的案例类,则为 MetricProcessor 创建一个伴随对象,并将其放在那里implicit val metricEncoder: Encoder[Metric] = Encoders.product& 要么放在特征的主体上,要么放在方法添加import MetricProcessor._- 顺便说一句,我会把这个方法定为最终的。
标签: scala apache-spark design-patterns apache-spark-sql apache-spark-dataset