我正在尝试对DataFrame应用否定过滤条件,如下所示。
!(`Ship Mode` LIKE '%Truck%')
哪个在下面抛出异常
Exception in thread "main" java.lang.RuntimeException: [1.3] failure: identifier expected
(!(`Ship Mode` LIKE '%Truck%'))
^
at scala.sys.package$.error(package.scala:27)
at org.apache.spark.sql.catalyst.SqlParser.parseExpression(SqlParser.scala:47)
at org.apache.spark.sql.DataFrame.filter(DataFrame.scala:748)
at Main.main(Main.java:73)
在MySQL中,同样的否定过滤条件也可以正常工作。如下请见
mysql> select count(*) from audit_log where !(operation like '%Log%' or operation like '%Proj%');
+----------+
| count(*) |
+----------+
| 129 |
+----------+
1 row in set (0.05 sec)
有人可以让我知道是否计划在以后的版本中将其修复在Spark DataFrames中,或者我是否应该提出JIRA。
最佳答案
看来您使用的是普通SQLContext
,其中不支持!
:
import org.apache.spark.sql.SQLContext
val sqlContext = new SQLContext(sc)
val data = Seq(("a", 1, 3), ("b", 2, 6), ("c", -1, 2))
val df = sqlContext.createDataFrame(data).toDF("x1", "x2", "x3")
df.registerTempTable("df")
sqlContext.sql("SELECT * FROM df WHERE ! (x2 > 2 OR x3 < 4)").show
// java.lang.RuntimeException: [1.25] failure: identifier expected
//
// SELECT * FROM df WHERE ! (x2 > 2 OR x3 < 4)
// ^
可以很容易地用
NOT
代替:sqlContext.sql("SELECT * FROM df WHERE NOT (x2 > 2 OR x3 < 4)").show
// +---+---+---+
// | x1| x2| x3|
// +---+---+---+
// | b| 2| 6|
// +---+---+---+
如果仍要使用
!
,则应使用HiveContext
:import org.apache.spark.sql.hive.HiveContext
val hiveContext = new HiveContext(sc)
val df1 = hiveContext.createDataFrame(data).toDF("x1", "x2", "x3")
df1.registerTempTable("df")
hiveContext.sql("SELECT * FROM df WHERE ! (x2 > 2 OR x3 < 4)").show
// +---+---+---+
// | x1| x2| x3|
// +---+---+---+
// | b| 2| 6|
// +---+---+---+