1

我正在尝试将 a 转换Dataframe为 a Dataset,java类结构如下:

A类:

public class A {

    private int a;

    public int getA() {
        return a;
    }

    public void setA(int a) {
        this.a = a;
    }
}

B类:

public class B extends A {

    private int b;

    public int getB() {
        return b;
    }

    public void setB(int b) {
        this.b = b;
    }
}

和 C 类

public class C {

    private A a;

    public A getA() {
        return a;
    }

    public void setA(A a) {
        this.a = a;
    }
}

数据框中的数据如下:

+-----+
|  a  |
+-----+
|[1,2]|
+-----+

当我尝试将 Encoders.bean[C](classOf[C]) 应用于数据帧时。当我检查 .isInstanceOf[B] 时,作为类中A实例的对象引用未返回 true,我将其视为 false。数据集的输出如下:BC

+-----+
|  a  |
+-----+
|[1,2]|
+-----+

我们如何在 foreach 中迭代 C 对象时获取 A 和 B 的所有字段?

代码 :-

object TestApp extends App {

  implicit val sparkSession = SparkSession.builder()
    .appName("Test-App")
    .config("spark.sql.codegen.wholeStage", value = false)
    .master("local[1]")
    .getOrCreate()


  var schema = new StructType().
    add("a", new ArrayType(new StructType().add("a", IntegerType, true).add("b", IntegerType, true), true))


  var dd = sparkSession.read.schema(schema).json("Test.txt")

  var ff = dd.as(Encoders.bean[C](classOf[C]))
  ff.show(truncate = false)



  ff.foreach(f => {
    println(f.getA.get(0).isInstanceOf[A])//---true
    println(f.getA.get(0).isInstanceOf[B])//---false
  })

文件内容:{"a":[{"a":1,"b":2}]}

4

1 回答 1

0

Spark-catalyst使用谷歌反射从 Java bean 中获取模式。请看一下JavaTypeInference.scala#inferDataType。此类使用 getter 来收集字段名称和 getter 的 returnType 来计算SparkType.

由于类具有以returnType asC命名的 getter ,反过来,具有与 returnType as 相同的getter ,将创建 Schema 作为从class派生的位置。getA()AAgetA()intstruct<a:struct<a:int>>struct<a:int>getAA

这个问题我能想到的解决办法是——

// Modify your class C to have Real class reference rather its super type
public class C {

    private B a;

    public B getA() {
        return a;
    }

    public void setA(B a) {
        this.a = a;
    }
}

输出-

root
 |-- a: struct (nullable = true)
 |    |-- a: integer (nullable = false)
 |    |-- b: integer (nullable = false)

+------+
|a     |
+------+
|[1, 2]|
+------+
于 2020-05-30T08:27:51.127 回答