为什么数据集的foreach方法不需要编码器,而map需要?

时间:2018-11-08 17:51:21

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

我有两个数据集: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]还是其他?

1 个答案:

答案 0 :(得分:4)

需要

TL; DR Encoder才能将结果转换为内部Spark SQL格式,对于foreach(或任何其他接收器)则不需要)。

只需看一下签名。 map

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

因此,它以通俗易懂的方式将记录从T转换为U,然后使用Encoder的{​​{1}}将结果转换为内部表示形式。

foreach

U

换句话说,它不会期望任何结果。由于没有要存储的结果,因此def foreach(f: (T) ⇒ Unit): Unit 已过时。