Spark数据帧到Java类的数据集
我想将作为Json读入的数据帧转换为给定类的数据集。到目前为止,当我能够编写自己的案例类时,这种方法非常有效Spark数据帧到Java类的数据集,java,scala,apache-spark,Java,Scala,Apache Spark,我想将作为Json读入的数据帧转换为给定类的数据集。到目前为止,当我能够编写自己的案例类时,这种方法非常有效 case class MyCaseClass(...) val df = spark.read.json("path/to/json") val ds = df.as[MyCaseClass] def myFunction(input: MyCaseClass): MyCaseClass = { // Do some validation and things inpu
case class MyCaseClass(...)
val df = spark.read.json("path/to/json")
val ds = df.as[MyCaseClass]
def myFunction(input: MyCaseClass): MyCaseClass = {
// Do some validation and things
input
}
ds.map(myFunction)
但是,现在我绑定到外部Java类(特别是thrift创建的类)。下面是一个更具体的自定义类示例:
Json:
类别:
class MyInnerClass(var inside: String, var map: Map[String, String]) extends java.io.Serializable {
def getInside(): String = {inside}
def setInside(newInside: String) {inside = newInside}
def getMap(): Map[String, String] = {map}
def setMap(newMap: Map[String, String]) {map = newMap}
}
class MyClass(var a: Int, var b: String, var wrapper: MyInnerClass) extends java.io.Serializable {
def getA(): Int = {a}
def setA(newA: Int) {a = newA}
def getB(): String = {b}
def setB(newB: String) {b = newB}
def getWrapper(): MyInnerClass = {wrapper}
def setWrapper(newWrapper: MyInnerClass) {wrapper = newWrapper}
}
所以我想做:
val json = spark.read.json("path/to/json")
json.as[MyClass]
然而,这意味着:
Unable to find encoder for type stored in a Dataset. Primitive type (Int, String, etc) and Product types (case classes) are supported by importing spark.implicits._ Support for serializing other types will be added in future releases.
所以,我发现了定制编码器:(和)
它抛出:
Try to map struct<a:bigint,b:string,wrapper:struct<inside:string,map:struct<k:string>>> to Tuple1, but failed as the number of fields does not line up
尝试将struct映射到Tuple1,但失败,因为字段数没有对齐
因此,如何将数据帧转换为自定义对象数据集。请尝试使用产品编码器,而不是使用kryo编码器:
val productMyClassEncoder = Encoders.product[MyClass]
当在方法中使用case类的声明时,我遇到了同样的问题(没有任何帮助)。将类移出方法后,
import spark.implicits.\u
工作正常这方面运气好吗?你能告诉我你是怎么做到的吗?这里也有同样的问题。我有一个使用Java类(和枚举)的解决方案,但我希望看到它也能使用Scala类和枚举。在我的例子中,我使用与读取JSON相同的方法创建了case类。我将case类定义移到了一个外部范围,它奇怪地工作了。我在浏览错误时偶然发现了这个解决方案。只有在我使用产品编码器并将案例类定义移到外部范围时,它才对我有效
Try to map struct<a:bigint,b:string,wrapper:struct<inside:string,map:struct<k:string>>> to Tuple1, but failed as the number of fields does not line up
val productMyClassEncoder = Encoders.product[MyClass]