如何加入两个Spark RDD

时间:2018-06-29 23:54:03

标签: scala apache-spark

我有2个火花RDD,第一个包含一些索引和ID(它们是字符串)之间的映射,第二个包含相关索引的元组

val ids = spark.sparkContext.parallelize(Array[(Int, String)](
      (1, "a"), (2, "b"), (3, "c"), (4, "d"), (5, "e"))).toDF("index", "idx")


val relationships = spark.sparkContext.parallelize(Array[(Int, Int)](
  (1, 3), (2, 3), (4, 5))).toDF("index1", "index2")

我想以某种方式加入这些RDD(或merge,sql或任何最佳Spark实践),使其最终具有相关ID:

合并后的RDD的结果应返回:

("a", "c"), ("b", "c"), ("d", "e")

任何想法我如何以最佳方式实现此操作而又不将任何RDD加载到内存映射中(因为在我的方案中,这些RDD可能加载数百万条记录)

1 个答案:

答案 0 :(得分:2)

您可以通过以下方法从views创建两个DataFrame来解决此问题

relationships.createOrReplaceTempView("relationships");
ids.createOrReplaceTempView("ids");

接下来运行以下SQL查询以生成所需的结果,该结果在relationshipsids视图之间执行内部联接以生成所需的结果

import sqlContext.sql;
val result = spark.sql("""select t.index1, id.idx from 
                                (select id.idx as index1, rel.index2 
                               from relationships rel
                               inner join
                               ids id on rel.index1=id.index) t
                         inner join
                         ids id
                         on id.index=t.index2
                      """);

result.show()

使用DataFrame而不创建views的另一种方法

relationships.as("rel").
join(ids.as("ids"),  $"ids.index" === $"rel.index1").as("temp").
join(ids.as("ids"), $"temp.index2"===$"ids.index").
select($"temp.idx".as("index1"), $"ids.idx".as("index2")).show