从另一个rdd搜索rdd的值

时间:2015-08-07 05:01:07

标签: scala apache-spark rdd

我正在使用Spark + Scala。我的rdd1有客户信息,即(id[name, address])。 rdd2只有知名客户的名字。现在我想找出rdd1中的客户是否高调。如何使用另一个rdd搜索?加入rdd对我来说并不是一个好的解决方案。

我的代码:

val result = rdd1.map( case (id, customer) => 
  customer.foreach ( c => 
    rdd2.filter(_ == c._1).count()!=0 ))

错误org.apache.spark.SparkException: RDD transformations and actions can only be invoked by the driver, not inside of other transformations;

2 个答案:

答案 0 :(得分:2)

你必须通过收集它来播放一个rdd。您可以广播较小的rdd以提高性能。

val bcastRdd = sc.broadcast(rdd2.collect)
rdd1.map(
   case (id, customer) => customer.foreach(c => 
        bcastRdd.value.filter(_ == c._1).count()!=0))

答案 1 :(得分:0)

您可以使用左外连接,以避免昂贵的操作,例如收集(如果您的RDD很大)

也像丹尼尔指出的那样,没有必要进行广播。

这是一个片段,可以帮助获得带有标志的RDD1,这标志着他是一个高调的客户或低调的客户。

val highProfileFlag = 1
val lowProfileFlag = 0 

// Keying rdd 1 by the name    
val rdd1Keyed = rdd1.map { case (id, (name, address)) => (name, (id, address)) }

// Keying rdd 2 by the name and adding a high profile flag
val rdd2Keyed = rdd2.map { case name => (name, highProfileFlag) }

// The join you are looking for is the left outer join
val rdd1HighProfileFlag = rdd1Keyed
.leftOuterJoin(rdd2Keyed)
.map { case (name, (id, address), highProfileString) => 
      val profileFlag = highProfileString.getOrElse(lowProfileFlag) 
      (id , (name, address, profileFlag))
}