Scala 在rdd中搜索另一个rdd中的值
我正在使用Spark+Scala。我的rdd1有客户信息,即(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.
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。我必须更新我的知识。混淆了内部联接和外部联接。在本例中,广播没有区别。闭包捕获的变量将被广播。当您想在多个阶段中使用某些内容时,您只需要显式广播。