我正在使用Spark和Scala。我有两个配对RDD。
rdd1 : RDD[(String, List[String])]
rdd2 : RDD[(String, List[String])]
两个RDD都以第一个值连接在一起。
val joinedRdd = rdd1.join(rdd2)
因此生成的RDD的类型为RDD[(String, (List[String], List[String]))]
。我想映射这个RDD并提取两个列表的元素,以便生成的RDD只包含这两个列表中的这些元素。
rdd1 (id, List(a, b))
rdd2 (id, List(d, e, f))
wantedResult (a, b, d, e, f)
我天真的方法是直接使用(i)
添加每个元素,如下所示:
val rdd = rdd1.join(rdd2)
.map({ case (id, lists) =>
(lists._1(0), lists._1(1), lists._2(0), lists._2(2), lists._2(3)) })
/* results in RDD[(String, String, String, String, String)] */
有没有办法获取每个列表的元素,而不是单独解决每个列表?类似于" lists._1.extractAll
"。有没有办法使用flatMap
来实现我想要实现的目标?
答案 0 :(得分:4)
您可以使用++
运算符简单地连接两个列表:
val res: RDD[List[String]] = rdd1.join(rdd2)
.map { case (_, (list1, list2)) => list1 ++ list2 }
可能更好的方法是避免携带可能非常大的List[String]
,将RDD分解为较小的(键值)对,将它们连接起来,然后执行groupByKey
:< / p>
val flatten1: RDD[(String, String)] = rdd1.flatMapValues(identity)
val flatten2: RDD[(String, String)] = rdd2.flatMapValues(identity)
val res: RDD[Iterable[String]] = (flatten1 ++ flatten2).groupByKey.values