[英]Effectively counting records after join in spark
這就是我正在做的。 我需要獲取一個數據集中存在的記錄數,而不是另一個數據集,然后再次加入第三個數據集以獲取其他一些列。
val tooCompare = dw
.select(
"loc",
"id",
"country",
"region"
).dropDuplicates()
val previous = dw
.select(
"loc",
"id",
"country",
"region"
).dropDuplicates()
val delta = tooCompare.exceptAll(previous).cache()
val records = delta
.join(
dw,//another dataset
delta
.col("loc").equalTo(dw.col("loc"))
.and(delta.col("id").equalTo(dw.col("id")))
.and(delta.col("country").equalTo(dw.col("country")))
.and(delta.col("region").equalTo(dw.col("region")))
)
.drop(delta.col("loc"))
.drop(delta.col("id"))
.drop(delta.col("country"))
.drop(delta.col("region"))
.cache()
}
val recordsToSend = records.cache()
val count = recordsToSend.select("loc").distinct().count()
有沒有更有效的方法來做到這一點? 我是 Spark 的新手。 我很確定我在這里遺漏了一些東西
我建議使用 SQL 使其更具可讀性。
首先,創建相關數據幀的臨時視圖。 不知道你有什么數據幀,所以像
dfToCompare.createOrReplaceTempView("toCompare")
previousDf.createOrReplaceTempView("previous")
anotherDataSet.createOrReplaceTempView("another")
然后,您可以繼續在一條 SQL 語句中完成所有操作
val records = spark.sql("""select loc, id, country,region
from toCompare c
inner join another a
on a.loc = c.loc
and a.id = p.id
and a.country = c.country
and a.region = c.region
where not exists (select null
from previous p
where p.loc = c.loc
and p.id = p.id
and p.country = c.country
and p.region = c.region""")
然后你可以像以前一樣繼續......
val recordsToSend = records.cache()
val count = recordsToSend.select("loc").distinct().count()
我認為您粘貼的代碼中可能存在一些錯誤,因為 tooCompare 和以前的代碼相同,+ 第三個數據集連接引用了 deAnon 但表上的 dw ....
對於此示例答案,假設您的當前表稱為“當前”,前一個稱為“上一個”,第三個表稱為“額外”。 然后:
val delta = current.join(
previous,
Seq("loc","id","country","region"),
"leftanti"
).select("loc","id","country","region").distinct
val recordsToSend = delta
.join(
extra,
Seq("loc", "id", "country", "region")
)
val count = recordsToSend.select("loc").distinct().count()
這可能更有效,但我很感激你評論它是否真的有效!
順便說一句:請注意,我使用 Seq[String] 作為連接參數(這要求兩個表上的列名相同,並且不會生成列的兩個副本)。 但是,您的原始連接邏輯可以寫得更簡潔一些,如下(使用我的命名約定):
val recordsToSend = delta
.join(
extra,
delta("loc") === extra("loc")
&& delta("id") === extra("id")
&& delta("country") === extra("country")
&& delta("region") === extra("region")
)
.drop(delta("loc"))
.drop(delta("id"))
.drop(delta("country"))
.drop(delta("region"))
更好的是編寫一個 drop 函數,讓您提供多個列,但我現在真的離題了 ;-)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.