这就是我在做什么。我需要获取一个数据集而不是其他数据集中存在的记录数,然后再次与第三个数据集结合以获取其他一些列。
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的新手。我很确定我在这里错过了一些东西
答案 0 :(得分:0)
我建议使用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()
答案 1 :(得分:0)
我认为您粘贴为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函数,该函数可以让您提供不止一列,但现在我真的不在讨论主题了;-)