如何从'scala.collection.mutable.wrappedarray$ofref'转换到自定义对象?

2fjabf4q  于 2021-05-27  发布在  Spark
关注(0)|答案(2)|浏览(838)

我们正在使用 spark 随着 Scala 在我们的项目中。
我们正在使用自定义 encoders 创造 spark datasets .
我们的数据集架构的类型如下:

(String, util.ArrayList[MyObject])

当我们执行df.printschema时,我们得到以下结果:

root
 |-- key: string (nullable = true)
 |-- listOfMyObject: array (nullable = true)
 |    |-- element: binary (containsNull = true)

myobject是scala case类,如下所示:

case class MyObject(key: String, dataList: java.util.ArrayList[MyObject2])

当我们在这个Dataframe上应用map函数时,

df.map((row) => {
val key  = row.get(0)
val values = row.get(1)
})

在运行时,行包含以下架构:

StructField(key,StringType,true)
StructField(myObject,ArrayType(BinaryType,true),true)

我们能够找回 String 值,但在尝试检索 util.ArrayList[MyObject] ,我们正在 scala.collection.mutable.WrappedArray$ofRef .
我们通过使用 ref.getClass 方法。
有解决这个问题的方法吗?
谢谢
阿努吉

b4qexyjb

b4qexyjb1#

尝试使用spark可以通过编码器管理的scala对象,在您的情况下,您可以更改 java.util.ArrayList 到一个简单的 List 如果列的顺序和类型正确,则仅使用以下简单行将dataframe转换为类类型的数据集:

case class MyObject(key: String, dataList: List[MyObject2])
val ds: Dataset[MyObject] = df.as[MyObject]

请记住,如果您的模式有一个数组,那么yo只能将其转换为list,而不能转换为array。

jdgnovmf

jdgnovmf2#

我会改变的 java.util.ArrayListscala.collection.immutable.List ```
package playground

import org.apache.spark.sql.SparkSession
// import java.util.ArrayList

object Casting {

val spark = SparkSession.builder()
.appName("Casting")
.config("spark.master", "local[*]")
.getOrCreate()

case class MyObject2(fname: String, age: Int)

// case class MyObject(key: String, dataList: ArrayList[MyObject2])
case class MyObject(key: String, dataList: List[MyObject2])

// val arrLst = new util.ArrayListMyObject2
// arrLst.add(MyObject2("Marie", 25))
// arrLst.add(MyObject2("Peter", 27))

val lst = List(MyObject2("Marie", 25),MyObject2("Peter", 27))

// val data: Seq[MyObject] = Seq(MyObject("key",arrLst))
val data: Seq[MyObject] = Seq(MyObject("key",lst))

def main(args: Array[String]): Unit = {

import spark.implicits._

try {
  val df = spark.createDataFrame(data)

  df.printSchema()
  df.map(row => {
    val key  = row.key
    val values = row.dataList
    (key, values)
  }).show(false)

  df.show()
} finally {
  spark.stop()
  println("Spark Session has stopped.")
}

}
}

root
|-- key: string (nullable = true)
|-- dataList: array (nullable = true)
| |-- element: struct (containsNull = true)
| | |-- fname: string (nullable = true)
| | |-- age: integer (nullable = false)

+-----+--------------------------+
|_1 |_2 |
+-----+--------------------------+
|Lucia|[[Marie, 25], [Peter, 27]]|
+-----+--------------------------+
``` ArrayList 它不是 Scala collection . 我会努力和你一起工作 Scala objects 那个 Spark 可以用它来管理 encoders .

相关问题