Scala 在rdd中搜索另一个rdd中的值

Scala 在rdd中搜索另一个rdd中的值,scala,apache-spark,rdd,Scala,Apache Spark,Rdd,我正在使用Spark+Scala。我的rdd1有客户信息,即(id,[姓名、地址])。rdd2只有知名客户的名字。现在我想知道rdd1中的客户是否高调。如何使用另一个rdd搜索一个rdd?加入rdd对我来说不是一个好的解决方案 我的代码: val result = rdd1.map( case (id, customer) => customer.foreach ( c => rdd2.filter(_ == c._1).count()!=0 )) 错误: org.

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

我的代码:

val result = rdd1.map( case (id, customer) => 
  customer.foreach ( c => 
    rdd2.filter(_ == c._1).count()!=0 ))
错误
org.apache.spark.SparkException:RDD转换和操作只能由驱动程序调用,不能在其他转换内部调用

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

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

您可以使用左外部联接,以避免昂贵的操作,如collect(如果您的RDD很大)

正如丹尼尔指出的,广播是不必要的

下面是一个代码片段,它可以帮助获取RDD1,其中带有一个标志,表示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))
}

“加入rdd对我来说似乎不是一个好的解决方案。”为什么不呢?因为rdd没有公共密钥,内部连接不会使已经巨大的rdd变得超级巨大吗?谢谢Paul。我必须更新我的知识。混淆了内部联接和外部联接。在本例中,广播没有区别。闭包捕获的变量将被广播。当您想在多个阶段中使用某些内容时,您只需要显式广播。