DropDuplicates没有提供预期的结果

时间:2019-03-22 15:07:26

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

我正在研究从传入的结构化数据中删除重复记录的用例(以HDFS上一个文件夹中的CSV文件的形式)。为了尝试此用例,我使用文件选项编写了一些示例代码,以查看是否可以从复制到文件夹(HDFS)的CSV中存在的记录中删除重复项。

在代码段下找到:

import org.apache.spark.sql.functions._
import org.apache.spark.sql.SparkSession
import spark.implicits._
import org.apache.spark.sql.types.{StructType, StructField, StringType, IntegerType}


val spark = SparkSession.builder.appName("StructuredNetworkWordCount").getOrCreate()
val userSchema = new StructType()
    .add("prod_code", "string")
    .add("bal", "integer")
    .add("v_txn_id", "string")
    .add("timestamp", "Timestamp")

val csvDF = spark.readStream.option("sep", ",")
                            .schema(userSchema)
                            .csv("/user/Temp")
csvDF.dropDuplicates("v_txn_id")
csvDF.createOrReplaceTempView("table1")

val dbDf2 = spark.sql("select prod_code, bal, v_txn_id, current_timestamp timestamp from table1")
dbDf2.writeStream.queryName("aggregates").outputMode("update").format("memory").start()

spark.sql("select * from aggregates").show();

现在,当我在具有重复记录的文件夹中复制文件时(通过v_txn_id),我仍然看到结果接收器从文件中获取了所有行:

P1,1000,TXNID1
P1,2000,TXNID2
P1,3000,TXNID2
P1,4000,TXNID3
P1,5000,TXNID3
P1,6000,TXNID4

csv文件中的所有这些行都移至结果“聚合”。我期望的是:

P1,1000,TXNID1
P1,3000,TXNID2
P1,5000,TXNID3
P1,6000,TXNID4

这是我第一次尝试使用状态进行结构化流式传输,请原谅我的琐碎问题。任何建议都会有很大帮助。

1 个答案:

答案 0 :(得分:0)

根据您的预期输出,我相信您需要根据prod_codev_txn_id列找到bal的最大值。为了实现输出,您可以在最终的aggregate表上使用窗函数(partition by)根据bal和{{1}查找prod_code的最大值}列创建了一个名为v_txn_id的临时列。然后在外部查询中,根据temp_balprod_codetemp_bal列选择不同的值。

v_txn_id

enter image description here 编辑1:

根据您的要求,请找到以下脚本,该脚本将根据spark.sql("select distinct prod_code,temp_bal as bal,v_txn_id from(select *,max(bal) over(partition by prod_code,v_txn_id) as temp_bal from aggregates) order by prod_code,v_txn_id").show() 的最新日期/时间运行。

v_txn_id

enter image description here

如果您有任何疑问,请告诉我,否则,请将此答案标记为已接受(刻度图标)。