我有一个字符串数据集,我使用可能失败的函数解析为案例类的数据集(例如,如果我尝试解析的数据不可用)。因此,该函数返回一个Option(Scala)。 所以我最终得到了一个Option [MyCaseClass]的数据集。
Spark似乎接受了数据集并对其进行处理,但如果解析失败则不会返回None
而是返回Some(MyCaseClass(null, null...))
。
以下是代码执行的示例:
recordsDs
.map { record =>
val maybeArticle = unmarshallArticle(record)
if (maybeArticle.isEmpty) {
println(s"Could not parse record $record into an article.")
}
maybeArticle
}
.filter(_.isDefined)
.map(_.get)
.collect().toList // Always returns a List(Some(Article(null, null), Some(Article...
的笔记本
我的猜测是,在序列化然后反序列化Option值时,Spark使用Some()构造函数而不是检查Option是Some还是None。
我显然可以在我的对象周围创建一个包装器,类似于MaybeArticle(article: Option[Article])
,但我想知道Spark是否可以正确处理Options的数据集?
答案 0 :(得分:2)
我认为解决方案是使用flatMap
。这是一个非常愚蠢的例子:
scala> val ds = Seq(("a1"), ("a2"), ("a4"), ("b1"), ("b2")).toDS
ds: org.apache.spark.sql.Dataset[String] = [value: string]
scala> ds.show
+-----+
|value|
+-----+
| a1|
| a2|
| a4|
| b1|
| b2|
+-----+
scala> val ds2 = ds.flatMap{x => if (x.contains("a")) Some(x) else None}
ds2: org.apache.spark.sql.Dataset[String] = [value: string]
scala> ds2.show
+-----+
|value|
+-----+
| a1|
| a2|
| a4|
+-----+
这样做的原因是因为Some
和None
的行为类似于可以使用flatMap
解压缩的集合(其中None
个元素被省略)。