基于列值的火花集连续计数器值

时间:2018-08-08 13:04:54

标签: java apache-spark apache-spark-sql

我们有必要根据输入记录设置计数器值:

 for e.g.
    record 1 ->    {subtradeid:100,amount:1000}
    record 2 ->    {subtradeid:100,amount:8000}
    record 3 ->    {subtradeid:200,amount:3000}
    record 4 ->    {subtradeid:300,amount:2000}
    record 5 ->    {subtradeid:300,amount:2000}
    record 6 ->    {subtradeid:500,amount:8000}
    record 7 ->    {subtradeid:500,amount:8000}
    record 8 ->    {subtradeid:500,amount:8000}

因此,每当执行者处理这些记录时,它都应该为这些记录中的每一个创建计数器字段,这对于每个子交易对象都应该是唯一的。

因此,对于所有具有subtradeid = 500的记录,它应设置连续的新字段(例如Portfolioid),并且无论执行者如何处理该记录,都不应重复该字段。 因此,如果执行者1处理subtradeid = 500的记录,设置Portfolioid = 1,并且如果执行者2处理subtradeid = 500的下一条记录,那么它应该设置Portfolioid = 2(即下一个计数器值)。

1 个答案:

答案 0 :(得分:0)

如果我的理解正确,您想为同一子贸易品种组中的每个记录的数据集添加一个额外的计数器列。批量处理可以简单地使用窗口函数来完成:

import org.apache.spark.sql.expressions.Window
val df = List((1,100,1000),(2,100,8000),(3,200,3000),(4,300,2000),(5,300,2000),(6,500,8000),(7,500,8000),(8,500,8000)).toDF("record","subtradeid","amount")
val w = Window.partitionBy(col("subtradeid")).orderBy(col("record"))

val res = df.withColumn("portfolioid",row_number().over(w))

包含

+------+----------+------+-----------+
|record|subtradeid|amount|portfolioid|
+------+----------+------+-----------+
|     4|       300|  2000|          1|
|     5|       300|  2000|          2|
|     6|       500|  8000|          1|
|     7|       500|  8000|          2|
|     8|       500|  8000|          3|
|     1|       100|  1000|          1|
|     2|       100|  8000|          2|
|     3|       200|  3000|          1|
+------+----------+------+-----------+

编辑:rank-> row_number取消假设record字段是主键的假设