如何通过spark RDD中的键连接两个哈希映射

时间:2015-03-26 05:51:47

标签: scala apache-spark spark-streaming

我有两个RDD,格式为

  

{string,HashMap [long,object]}

我想对它们执行连接操作,以便相同键的hashmap在scala中合并。

RDD1-> {string1,HashMap[{long a,object},{long b,object}]
RDD2-> {string1,HashMap[{long c,object}]

加入两个RDD后,它应该像

RDD->{string1,HashMap[{long a,object},{long b,object},{long c,object}]

任何帮助都将受到赞赏,同时我也是scala和spark的新手。

2 个答案:

答案 0 :(得分:3)

更新:更简单的方法就是获取联合,然后按键减少:

(rdd1 union rdd2).reduceByKey(_++_)

较旧的解决方案,仅供参考。这也可以通过cogroup来完成,join收集一个或两个RDD中的键的值(而++将省略仅在一个原始RDD中具有键的值)。请参阅ScalaDoc

然后,我们使用reduce连接值列表以形成单个值列表,最后将mapValues值(Maps)连接到单个Map。

最后两个步骤可以合并为一个val rdd1 = sc.parallelize(List("a"->Map(1->"one", 2->"two"))) val rdd2 = sc.parallelize(List("a"->Map(3->"three"))) 操作:

使用此数据......

val x = (rdd1 cogroup rdd2).mapValues{ case (a,b) => (a ++ b).reduce(_++_)}

x foreach println

> (a,Map(1 -> one, 2 -> two, 3 -> three))

...在火花壳中:

{{1}}

答案 1 :(得分:1)

您可以通过加入两个RDD并将合并函数应用于地图的元组来实现:

  

def join [W](其他:RDD [(K,W)],numSplits:Int):RDD [(K,(V,W))]   返回包含所有具有匹配键的元素对的RDD   这个和其他。每对元素将返回为(k,(v1,   v2))元组,其中(k,v1)在此,而(k,v2)在其他中。施行   整个群集中的散列连接。

     

def mapValues [U](f:(V)⇒U):RDD [(K,U)]传递每个值   键值对RDD通过map函数而不改变键;   这也保留了原始RDD的分区。

假设有一个函数合并,如Best way to merge two maps and sum the values of same key?

中所述
def [K] merge(a:K,b:K):K = ???

可能就像

def merge(a:Map[K,V],b:Map[K,V]) = a ++ b

鉴于此,RDD可以先加入

val joined = RDD1.join(RDD2) 

然后映射

val mapped = joined.mapValues( v => merge(v._1,v._2))

结果是带有(Key,合并的Map)的RDD ..