更新对象的RDD

时间:2019-06-18 19:28:05

标签: scala apache-spark rdd custom-object

我刚刚开始学习scala,并面临一些有关对象RDD操纵的问题。

我遇到以下链接中所述的相同问题

Update the internal state of RDD elements

还有其他方法可以解决上述链接中所述的问题吗?还可以使用数据集或数据框来实现我们想要做的事情吗?

1 个答案:

答案 0 :(得分:3)

不可变性是功能编程的关键概念之一。您无法更改RDD或内部数据,但可以基于旧RDD中的数据创建新的RDD

我从您问题的链接中修改了示例,以显示这种转换通常是什么样子。

//just case class with foo and bar fields that can be empty.
case class Test (foo: Option[Double], bar: Option[Double], someOtherVal: String)

// as you can see this is not actually "update"
// it creates new Test with "updated" foo and bar fields 
// NOTE: this logic usually lives outside data object 
def updateFooBar(t: Test) = Test(Some(Math.random()), Some(Math.random()),t.someOtherVal)


val testList = Array.fill(5)(Test(None,None,"someString"))
val testRDD = sc.parallelize(testList)

//creates new RDD based on old one by applying updateFooBar to each element. 
val newRdd = testRDD.map{ x => updateFooBar(x) }
//or just  val newRdd = testRDD.map(updateFooBar)

newRdd.collect().foreach { x=> println(x.foo+"~"+x.bar+"~"+x.someOtherVal) }

您可以像Dataset一样完全转换RDD

val newDs = testRDD.toDS().map( x => updateFooBar(x))

或使用Dataframe

import org.apache.spark.sql.functions.typedLit

val newDf = testRDD.toDF()
  .withColumn("foo",typedLit(Some(Math.random())))
  .withColumn("bar",typedLit(Some(Math.random())))