Scala 映射内的迭代查找 def描述(列表:数组[字符串]):数组[字符串]={ 对于(y)(描述(x._1),x._2))

Scala 映射内的迭代查找 def描述(列表:数组[字符串]):数组[字符串]={ 对于(y)(描述(x._1),x._2)),scala,apache-spark,iteration,key-value,rdd,Scala,Apache Spark,Iteration,Key Value,Rdd,是我的当前代码。我希望不使用collect来执行此操作。modulelookup和brandlookup是RDD。如何执行此操作?如果modulelookup和brandlookup相对较小,您可以将其转换为广播变量,并用于映射,如下所示: def description(list:Array[String]): Array[String] = { for (y <- list) yield modulelookup.lookup(take(4)) + " " + brandlooku

是我的当前代码。我希望不使用collect来执行此操作。modulelookup和brandlookup是RDD。如何执行此操作?

如果
modulelookup
brandlookup
相对较小,您可以将其转换为广播变量,并用于映射,如下所示:

def description(list:Array[String]): Array[String] = {
  for (y <- list) yield modulelookup.lookup(take(4)) + " " + brandlookup.lookup(y.drop(4)).toString()
}

val printRDD = outputRDD.collect().map(x=> (description(x._1),x._2))
如果没有,则没有有效的方法处理此问题。您可以尝试
flatMap
join
groupByKey
,但对于任何大型数据集,这种组合可能会非常昂贵

val modulelookupBD = sc.broadcast(modulelookup.collectAsMap)
val brandlookupBD = sc.broadcast(brandlookup.collectAsMap)

def description(list:Array[String]): Array[String] = list.map(x => {
  val module =  modulelookupBD.value.getOrElse(x.take(4), "")
  val brand  = brandlookupBD.value.getOrElse(x.drop(4), "")
  s"$module $brand"
})

val printRDD = outputRDD.map{case (xs, y) => (description(xs), y)}

用数据帧替换RDD可以减少样板代码,但性能仍然是个问题。

这是一个彻底的答案。谢谢。
val indexed = outputRDD.zipWithUniqueId
val flattened = indexed.flatMap{case ((xs, _), id) => xs.map(x => (x, id))}

val withModuleAndBrand = flattened
  .map(xid => (xid._1.take(4), xid))
  .join(modulelookup)
  .values
  .map{case ((x, id), module) => (x.drop(4), (id, module))}
  .join(brandlookup)
  .values
  .map{case ((id, module), brand) => (id, s"$module $brand")}
  .groupByKey

val final = withModuleAndBrand.join(
  indexed.map{case ((_, y), id) => (id, y)}
).values