我想使用窗口期执行结构化流式聚合。给出以下数据模式。目标是根据用户过滤最新发生的事件。然后汇总每个位置的每种事件类型的计数。
time location user type
1 A 1 one
2 A 1 two
1 B 2 one
2 B 2 one
1 A 3 two
1 A 4 one
示例输出:
location countOne countTwo
A 1 2
B 1 0
类似以下内容:
val aggTypes = df
.select($"location", $"time", $"user", $"type")
.groupBy($"user")
.agg(max($"timestamp") as 'timestamp)
.select("*")
.withWatermark("timestamp", conf.kafka.watermark.toString + " seconds")
.groupBy(functions.window($"timestamp", DataConstant.t15min.toString + " seconds", DataConstant.t1min.toString + " seconds", $"location")
.agg(count(when($"type" === "one", $"type")) as 'countOne, count(when($"type" === "two", $"type" as 'countTwo)))
.drop($"window")
由于结构化流式传输不支持多个聚合,因此流式DataFrames / Datasets不支持非基于时间的流。我不确定是否有可能在1个流查询中实现所需的输出。
感谢任何帮助。
答案 0 :(得分:0)
flatMapGroups是一个聚合API,它将函数应用于数据集中的每个组。它仅在分组数据集上可用.flatMapGroups不支持增加随机开销的部分聚合。因此,仅使用此API执行适合内存的小批量聚合。还建议使用reduce函数或聚合器。 https://spark.apache.org/docs/2.0.2/api/java/org/apache/spark/sql/expressions/Aggregator.html
val count = words.groupByKey(x => x)
.flatMapGroups
{
case (x, iterator) ⇒ Iterator((x, iterator.length))
}.toDF("x", "count")
count.writeStream.format("console").outputMode(OutputMode.Append())