尽管在撰写本文时拉斐尔的回答是完全正确的,但火花不断发展......
运算符 !== 自 2.0 版起已弃用,但您可以使用 =!= 解决上述优先级问题,而无需使用括号。查看源码中对应的cmets:
https://github.com/apache/spark/blob/branch-2.2/sql/core/src/main/scala/org/apache/spark/sql/Column.scala#L319-L320
详细回答:
我还想指出一开始对我来说并不明显的一些事情。
有DataFrame (DF) 和DataSet (DS) 的概念,它们也将它们在上述上下文中的用法分为:
1)由催化剂解释的字符串(错误仅在运行时被捕获) - DF和DS
案例类 NullStrings(n: Int, s: String)
val df = spark.sparkContext.parallelize(Seq(
(1, "abc"),
(2, "ABC"),
(3, null),
(4, ""))
).toDF("n", "s")
df.filter("s is not null and s != ''").show()
+---+---+
| n| s|
+---+---+
| 1|abc|
| 2|ABC|
+---+---+
2) 使用Column 概念的数据帧语法($ 和spark.implicits._ 导入)部分编译检查:
df.filter($"s" =!= "" || $"s" =!= null).show()
但实际上=!= 忽略了空值(参见<=> 进行空值安全比较),因此下面等于
df.filter($"s" =!= "").show()
+---+---+
| n| s|
+---+---+
| 1|abc|
| 2|ABC|
+---+---+
3) 数据集
val ds = df.as[NullStrings]
ds.filter(r => r.s != null && r.s.nonEmpty).show()
+---+---+
| n| s|
+---+---+
| 1|abc|
| 2|ABC|
+---+---+
注意如果你在case类中使用Option,你必须处理它,而不是简单的字符串。
case class NullStringsOption(n: Int, s: Option[String])
val ds1 = df.as[NullStringsOption]
ds1.filter(_.s.exists(_.nonEmpty)).show()