类型为 Any 的数据框到数据集

Dataframe to Dataset which has type Any

我最近从 Spark 1.6 转移到了 Spark 2.X,我也想尽可能地从 Dataframes 转移到 Datasets。我试过这样的代码

case class MyClass(a : Any, ...)

val df = ...
df.map(x => MyClass(x.get(0), ...))

如您所见,MyClass 有一个类型为 Any 的字段,因为我在编译时不知道我用 x.get(0) 检索的字段类型。可以是long、string、int等

但是,当我尝试执行类似于您在上面看到的代码时,出现异常:

java.lang.ClassNotFoundException: scala.Any

经过一些调试,我意识到引发了异常,不是因为我的数据是 Any 类型,而是因为 MyClass 的类型是 Any。那么我该如何使用数据集呢?

除非你对 感兴趣,比如 Encoders.kryo:

import org.apache.spark.sql.Encoders

case class FooBar(foo: Int, bar: Any)

spark.createDataset(
  sc.parallelize(Seq(FooBar(1, "a")))
)(Encoders.kryo[FooBar])

spark.createDataset(
  sc.parallelize(Seq(FooBar(1, "a"))).map(x => (x.foo, x.bar))
)(Encoders.tuple(Encoders.scalaInt, Encoders.kryo[Any]))

你不知道。 Dataset 中的所有字段/列都必须是已知的同类类型,范围内有一个隐式 EncoderAny 那里根本没有地方。

UDT API 提供了更多的灵活性并允许有限的多态性,但它是私有的,与 Dataset API 不完全兼容,并且会带来显着的性能和存储损失。

如果对于给定的执行所有相同类型的值,您当然可以创建专门的 类 并决定在 运行 时使用哪一个。