如何在Spark Scala中进行类型安全数据集左联接 背景

如何在Spark Scala中进行类型安全数据集左联接 背景,scala,apache-spark,apache-spark-dataset,Scala,Apache Spark,Apache Spark Dataset,关于Spark的Dataset API实际上如何不提供完全类型安全的联接,已经有很多争论,但我很固执,所以我真的想尝试尽可能接近它(不使用外部库) 我可以通过内部连接来实现这一点。但是,我有时想做一个左(或右)外部联接,但不知道如何获得正确的类型签名 问题: 具体来说, 如果无论外部联接类型(左)如何,此函数都不返回任一侧的选项,那么如何使用Dataset.joinWith(rights,condition,“left”) 看起来要么需要在“外部”侧返回一个选项(如果执行左连接,则返回右侧),要

关于Spark的Dataset API实际上如何不提供完全类型安全的联接,已经有很多争论,但我很固执,所以我真的想尝试尽可能接近它(不使用外部库)

我可以通过内部连接来实现这一点。但是,我有时想做一个左(或右)外部联接,但不知道如何获得正确的类型签名

问题: 具体来说,

如果无论外部联接类型(左)如何,此函数都不返回任一侧的选项,那么如何使用Dataset.joinWith(rights,condition,“left”)

看起来要么需要在“外部”侧返回一个选项(如果执行左连接,则返回右侧),要么根本不返回不可连接的行(即,将成为内部连接而不是真正的外部连接)。不知何故,当我将“外部”字段映射到我的合并表中时,我需要让它们为空,但如果我将模式匹配“外部”行作为选项,它会阻止我。

TL;博士 Spark的Dataset API为整个不可连接的“外部”记录返回null

。。。字段级别不是空值(如SQL)或记录或字段级别的选项,您可以简单地进行匹配
:(..
简而言之,
joinWith
函数与类型签名有关,并随意返回一个静默的
null
,而不是指定的case类(或类型)

解决方案
  • 在类型签名和模式匹配中,就像它将返回有效记录一样(例如,不要在选项中包装模式匹配,因为这与它们的类型签名不匹配)
  • 但是,在实际使用该字段之前,请创建一个新的val,将可能为空的“外部”记录包装到一个选项中
例子 这应该是有效的scala代码(假设您已经设置了spark上下文并定义了数据集和案例类),但我还没有测试它

val joinedDs=leftDs
.joinWith(rightDs,leftDs(“键字段”)==rightDs(“键字段”),“左”)
.map{x=>{
val l=x._1//在左侧
val r=Option(x._2)//对右侧进行别名和选项化
ResultCaseClass(//在别处定义
l、 重点领域,
l、 non_key_字段,//可能是一个选项,也可能不是-就像在leftDs中显示的那样
option\u field=r.map(\u.regular\u field),//将非option rights变为option
reoption\u field=r.flatMap(\uu.ready\u一个\u选项)//展平rightDs选项
)
}}