有效地将数据帧的连接和未连接数据与其他数据帧进行连接

grv*_*grv 3 join apache-spark rdd apache-spark-sql

我有两个数据框 A 和 B。它们有不同的模式。

我想从数据帧 A 中获取在键上与 B 连接的记录以及未连接的记录,我也想要这些。

这可以在单个查询中完成吗?因为两次检查相同的数据会降低性能。DataFrame A 的大小比 B 大得多。Dataframe B 的大小约为 50Gb-100GB。因此在这种情况下我不能广播 B。

我可以接受得到一个 Dataframe C 作为结果,它可以有一个分区列“Joined”,其值为“Yes”或“No”,表示 A 中的数据是否与 B 结合。

如果A有重复怎么办?我不想要它们。我想稍后我会在 C 数据帧上执行一个 recudeByKey 。对此有什么建议吗?

我正在使用 Hive 表以 ORC 文件格式将数据存储在 HDFS 上。用 scala 编写代码。

Gle*_*olt 5

是的,您只需要进行左外连接:

import sqlContext.implicits._

val A = sc.parallelize(List(("id1", 1234),("id1", 1234),("id3", 5678))).toDF("id1", "number")
val B = sc.parallelize(List(("id1", "Hello"),("id2", "world"))).toDF("id2", "text")

val joined = udf((id: String) => id match {
  case null => "No"
  case _ => "Yes"
})

val C = A
  .distinct
  .join(B, 'id1 === 'id2, "left_outer")
  .withColumn("joined",joined('id2))
  .drop('id2)
  .drop('text)
Run Code Online (Sandbox Code Playgroud)

这将产生一个C:[id1: string, number: int, joined: string]如下所示的数据框:

[id1,1234,Yes]
[id3,5678,No]
Run Code Online (Sandbox Code Playgroud)

请注意,我添加了一个distinct来过滤掉其中的重复项A,并且最后一列C表示是否已加入。

编辑:根据 OP 的评论,我添加了drop从 B 中删除列的行。