问题描述
TL;DR:是否有与以下示例等效的类型安全
import spark.implicits._
val words = ... // streaming DataSet of schema: case class Record(timestamp: Timestamp,word: String)
// Group the data by window and word and compute the count of each group
val windowedCounts = words
.withWatermark("timestamp","10 minutes")
.groupBy(
window($"timestamp","10 minutes","5 minutes"),$"word")
.count()
我真的很喜欢 Spark 的类型安全 API,避免列名中的任何拼写错误。 我了解 Aggregator 类以及如何构建自己的聚合器。
但是我不知道如何应用 withWatermark
并以类型安全的方式构建 window
列?
您是否知道是否已经存在任何 API 或库?如果没有,您有什么好的解决方案吗?
目前,我最好的解决方案是调用 WindowOperator
将 Dataset[REC]
转换为 Dataset[TimeWindowed[REC]]
,如下所示:
case class TimeWindowed[REC](data: REC,timeWindow: TimeWindow)
case class TimeWindow(start: java.sql.Timestamp,end: java.sql.Timestamp)
我正在考虑将其更改为 Dataset[(TimeWindow,REC)]
之类的内容,与 ...byKey
函数系列 (Dataset[(K,REC)]
) 的返回类型相比,它可能更惯用。但我没有设法找到一个令人满意的解决方案。
解决方法
如果您使用的是 Spark 3,有一个实用方法可以让您安全地构造间隔字符串(例如,避免任何拼写错误):
import org.apache.spark.sql.catalyst.util.IntervalUtils
import org.apache.spark.sql.types.Decimal
val zeroSec = Decimal(0,Decimal.MAX_LONG_DIGITS,6)
IntervalUtils.makeInterval(years = 0,months = 0,weeks = 0,days = 0,hours = 0,mins = 10,secs = zeroSec).toString