2

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

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

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

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],还是别的什么?

4

1 回答 1

5

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

看看签名就知道了。map

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

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

foreach另一方面是

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

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

于 2018-11-08T18:19:01.313 回答