我正在使用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
;
答案 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))
}