【问题标题】:Why doesn't dataset's foreach method require an encoder, but map does?为什么 dataset 的 foreach 方法不需要编码器,但 map 需要?
【发布时间】:2018-11-08 17:51:21
【问题描述】:

我有两个数据集:Dataset[User]Dataset[Book] 其中 UserBook 都是案例类。我像这样加入他们:

val joinDS = ds1.join(ds2, "userid")

如果我尝试对joinDS 中的每个元素使用map,编译器会抱怨缺少编码器:

not enough arguments for method map: (implicit evidence$46: org.apache.spark.sql.Encoder[Unit])org.apache.spark.sql.Dataset[Unit]. Unspecified value parameter evidence$46. Unable to find encoder for type stored in a Dataset.

但如果我使用foreach 而不是map,则不会出现同样的错误。为什么foreach 也不需要编码器?我已经从 spark 会话中导入了所有隐式,那么当数据集是连接两个包含案例类的数据集的结果时,为什么 map 需要编码器?另外,我从那个连接中得到什么类型的数据集?是Dataset[Row],还是别的什么?

【问题讨论】:

  • 很确定你不能编码Unit

标签: scala apache-spark apache-spark-dataset apache-spark-encoders


【解决方案1】:

TL;DR 需要 Encoder 将结果转换为内部 Spark SQL 格式,在 foreach(或任何其他接收器)的情况下不需要这样做。

看看签名。 map

def map[U](func: (T) ⇒ U)(implicit arg0: Encoder[U]): Dataset[U] 

简单来说,它将记录从T 转换为U,然后使用UEncoder 将结果转换为内部表示。

另一方面,foreach

def foreach(f: (T) ⇒ Unit): Unit 

换句话说,它不期望任何结果。由于没有要存储的结果,Encoder 已经过时了。

【讨论】:

  • @vaer-k 那么它需要Encoder[T],而不是Encoder[U](或两者兼有)。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-08-04
  • 2020-05-03
  • 2012-05-17
  • 1970-01-01
  • 2010-11-02
  • 2020-09-02
  • 2014-07-24
相关资源
最近更新 更多