2015-10-22 223 views
2

我想在DataFrame上應用一個否定的過濾條件,如下所示。Spark數據幀否定過濾條件

!(`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) 

任何人都可以請讓我知道如果這個計劃將固定星火DataFrames在將來的版本或者我應該提出一個JIRA。

+1

您是否嘗試過使用「不像」? – ccheneson

+0

是的,但我不想用不喜歡,因爲表達式可能會變得相當複雜,我只是想整體否定它們。 –

+0

好的。你有沒有考慮過使用'rdd' +'filterNot',這樣你就可以'registerTable'並跳過'!像在你的查詢? – ccheneson

回答

5

它看起來像你使用普通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| 
// +---+---+---+ 
+0

非常感謝zero323它的作品! –