merge在scala中使用HashMap的键设置'元素

时间:2017-06-06 13:04:38

标签: scala apache-spark

我希望有一种简单的方法可以解决这个问题 我有两个RDD

g.vertices
(4,Set(5, 3))
(0,Set(1, 4))
(1,Set(2))
(6,Set())
(3,Set(0))
(5,Set(2))
(2,Set(1))

maps
Map(4 -> Set(5, 3))
Map(0 -> Set(1, 4))
Map(1 -> Set(2))
Map(6 -> Set())
Map(3 -> Set(0))
Map(5 -> Set(2))
Map(2 -> Set(1))

我该怎么办?

(4,Map(5 -> Set(2), 3 -> Set(0)))
(0,Map(1 -> Set(2), 4 -> Set(5, 3)))
(1,Map(2 -> Set(1)))
(6,Map())
(3,Map(0 -> Set(1, 4)))
(5,Map(2 -> Set(1)))
(2,Map(1 -> Set(2)))

我想将map的键与set的元素组合在一起,所以我想更改sets的元素(将它们与map的键合并)

我想过

val maps = g.vertices.map { case (id, attr) => HashMap(id -> attr) }

g.mapVertices{case (id, data) => data.map{case vId => maps.
  map { case i if i.keySet.contains(vId) => HashMap(vId -> i.values) } }}

但我有错误

  

org.apache.spark.SparkException:RDD转换和操作可以   只能由驱动程序调用,而不是在其他转换内部调用;   例如,rdd1.map(x => rdd2.values.count()* x)无效,因为   值转换和计数操作不能在里面执行   rdd1.map转换。有关更多信息,请参阅SPARK-5063。

1 个答案:

答案 0 :(得分:1)

这是join的一个简单用例。在以下代码中,Ag.vertices中的键的类型,KVmaps的键和值类型:

def joinByKeys[A, K, V](sets: RDD[(A, Set[K])], maps: RDD[Map[K, V]]): RDD[(A, Map[K, V])] = {
  val flattenSets = sets.flatMap(p => p._2.map(_ -> p._1)) // create a pair for each element of vertice's sets
  val flattenMaps = maps.flatMap(identity)                 // create an RDD with all indexed values in Maps
  flattenMaps.join(flattenSets).map{                       // join them by their key
    case (k, (v, a)) => (a, (k, v))                        // reorder to put the vertexId as id
  }.aggregateByKey(Map.empty[K, V])(_ + _, _ ++ _)         // aggregate the maps

}