有效地加入,而不是将数据框的数据加入到其他数据框中

时间:2016-08-03 05:09:41

标签: join apache-spark apache-spark-sql rdd spark-dataframe

我有两个数据帧可以说是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中编写代码。

1 个答案:

答案 0 :(得分:4)

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

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)

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

[id1,1234,Yes]
[id3,5678,No]

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

  

编辑:在OP发表评论后,我添加了drop行以从B中删除列。