我正在研究从传入的结构化数据中删除重复记录的用例(以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
这是我第一次尝试使用状态进行结构化流式传输,请原谅我的琐碎问题。任何建议都会有很大帮助。
答案 0 :(得分:0)
根据您的预期输出,我相信您需要根据prod_code
和v_txn_id
列找到bal的最大值。为了实现输出,您可以在最终的aggregate
表上使用窗函数(partition by
)根据bal
和{{1}查找prod_code
的最大值}列创建了一个名为v_txn_id
的临时列。然后在外部查询中,根据temp_bal
,prod_code
和temp_bal
列选择不同的值。
v_txn_id
根据您的要求,请找到以下脚本,该脚本将根据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
如果您有任何疑问,请告诉我,否则,请将此答案标记为已接受(刻度图标)。