[英]Spark streaming: keep the most recent value in a group
我有一個 stream 之類的
+------+-------------------+------+
|group | time| label|
+------+-------------------+------+
| a|2020-01-01 10:49:00|red |
| a|2020-01-01 10:51:00|yellow|
| a|2020-01-01 12:49:00|blue |
| b|2020-01-01 12:44:00|red |
| b|2020-01-01 12:46:00|blue |
| c|2020-01-01 12:46:00|green |
+------+-------------------+------+
我想使用火花流只為每個組保留最近的時間。
用火花 dataframe 我會使用 window function 作為
val window = {
Window
.partitionBy("group")
.orderBy($"time".desc)
}
df
.withColumn("rn",row_number.over(window))
.filter("rn = 1")
.drop("rn")
.show()
或者
df
.orderBy($"time".desc)
.dropDuplicates("group")
在火花流中執行相同操作的最佳方法是什么,以及如何以僅存儲最新解決方案的方式保存結果?
更新:我試圖在最近的時間每組只保留一行。 是否可以為此目的使用帶有mapGroupsWithState
的狀態轉換?
在 Spark Structured Streaming 中進行聚合時,您需要首先定義一個Window
。 通過這個Window 操作,您定義了將在哪個時間間隔計算您的聚合(“最大時間,按“組”列分組”)。
假設您計划在 5 分鍾(非滑動)window 內獲得最大時間,那么您將定義:
val df = spark.readStream
.format("kafka")
[...]
.selectExpr("CAST(value AS STRING) as group", "timestamp")
val dfGrouped = df
.select(
col("group"),
col("timestamp"),
unix_timestamp(col("timestamp"), "yyyy-MM-dd HH:mm:ss").alias("time_unix"))
.groupBy(col("group"), window($"timestamp", "5 minutes"))
.agg(max("time_unix").alias("max_time_unix"))
.withColumn("time", col("max_time_unix").cast(TimestampType))
.drop("window", "max_time_unix")
需要注意的是,最大值的聚合僅適用於數值,因此,轉換為unix_timestamp
,如上所示。
根據Output Modes ,您可以選擇update
模式以僅獲取組上的更新。 確保您的 output 接收器(例如控制台或數據庫)能夠處理更新並且不會創建重復項。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.