Spark 2选项的Spark 2数据集

时间:2016-11-09 15:11:07

标签: scala apache-spark spark-dataframe scala-option

我有一个字符串数据集,我使用可能失败的函数解析为案例类的数据集(例如,如果我尝试解析的数据不可用)。因此,该函数返回一个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...

这是一个说明案例https://databricks-prod-cloudfront.cloud.databricks.com/public/4027ec902e239c93eaaa8714f173bcfc/4480125715694487/1289561535151709/7956941984681624/latest.html

的笔记本

我的猜测是,在序列化然后反序列化Option值时,Spark使用Some()构造函数而不是检查Option是Some还是None。

我显然可以在我的对象周围创建一个包装器,类似于MaybeArticle(article: Option[Article]),但我想知道Spark是否可以正确处理Options的数据集?

1 个答案:

答案 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|
+-----+

这样做的原因是因为SomeNone的行为类似于可以使用flatMap解压缩的集合(其中None个元素被省略)。