我应该在Spark Scala中使用max还是rank

时间:2018-09-21 15:28:19

标签: scala apache-spark apache-spark-sql

今天,我遇到了一个问题,其中我有对特定表的更新事件,并希望每个唯一项都具有最新更新。

例如,我们在HDFS中有PeopleAction数据。这个人可以在网站上执行许多操作,例如创建,共享等。这里的问题是我想要每个人的最新操作。 PeopleAction看起来像

+--------+------+----------+
|personId|action|      time|
+--------+------+----------+
|       1|  like|1537542754|
|       1| share|1537542700|
|       2|create|1537542700|
+--------+------+----------+

因此有两种方法可以实现这一目标 在personId上创建一个Window,按时间降序排列,然后在窗口上的DataFrame上排名。选择等级= 1 像下面这样

val window = Window.partitionBy("personId").orderBy(col("time").desc)
df.withColumn("rn", row_number.over(window)).where(col("rn") === 1).drop("rn").show()
+--------+------+----------+
|personId|action|      time|
+--------+------+----------+
|       1|  like|1537542754|
|       2|create|1537542700|
+--------+------+----------+

或者我们可以在数据框中创建一个新列,该列将通过(personId上的窗口(此处未排序))获得max(time)。然后我们选择时间=== LatestTime的列。如下所示:

val window = Window.partitionBy("personId")
df.withColumn("latestTime", max(col("time")).over(window)).where(col("latestTime") === col("time")).drop("latestTime").show()
+--------+------+----------+
|personId|action|      time|
+--------+------+----------+
|       1|  like|1537542754|
|       2|create|1537542700|
+--------+------+----------+

所以,基本上我的问题是,这里应该首选哪种方式。我觉得第二种方法,我们只取max应该会更有效率,因为它不需要对整个Dataframe进行排序,并且某种方式,如果spark很聪明,它将一次又一次地避免窗口上的max,再次是O(N),而另一种方法是O(Nlog(N))

0 个答案:

没有答案