Scala 我如何使用;“不象”;在spark sql中?

Scala 我如何使用;“不象”;在spark sql中?,scala,apache-spark,apache-spark-sql,Scala,Apache Spark,Apache Spark Sql,rlike工作正常,但not rlike会抛出错误: scala> sqlContext.sql("select * from T where columnB rlike '^[0-9]*$'").collect() res42: Array[org.apache.spark.sql.Row] = Array([412,0], [0,25], [412,25], [0,25]) scala> sqlContext.sql("select * from T where columnB

rlike
工作正常,但
not rlike
会抛出错误:

scala> sqlContext.sql("select * from T where columnB rlike '^[0-9]*$'").collect()
res42: Array[org.apache.spark.sql.Row] = Array([412,0], [0,25], [412,25], [0,25])

scala> sqlContext.sql("select * from T where columnB not rlike '^[0-9]*$'").collect()
java.lang.RuntimeException: [1.35] failure: ``in'' expected but `rlike' found


val df = sc.parallelize(Seq(
  (412, 0),
  (0, 25), 
  (412, 25), 
  (0, 25)
)).toDF("columnA", "columnB")

或者它是问题的继续?

没有任何东西不象rlike,但在正则表达式中,有一种称为负前瞻的东西,这意味着它将给出不匹配的单词

对于上面的查询,您可以使用下面的正则表达式。比方说,您希望列B不以数字“0”开头

然后你可以这样做

sqlContext.sql("select * from T where columnB rlike '^(?!.*[1-9]).*$'").collect() 
Result: Array[org.apache.spark.sql.Row] = Array([412,0])

我的意思是,你必须用regex来否定比赛,而不是rlike。Rlike只是匹配您要求匹配的正则表达式。如果您的正则表达式告诉它不匹配,它就会应用它,如果您的正则表达式用于匹配,它就会这样做。

我知道您的问题有点老了,但以防万一:您是否只是尝试了scala的一元“!”运算符

在java中,您可以这样做:

DataFrame df = sqlContext.table("T");
DataFrame notLikeDf = df.filter(
  df.col("columnB").rlike("^[0-9]*$").unary_$bang()
);

在pyspark中,我是这样做的:

df = load_your_df()

matching_regex = "yourRegexString"

matching_df = df.filter(df.fieldName.rlike(matching_regex))

non_matching_df = df.subtract(matching_df)

以上答案建议使用消极前瞻。这在某些情况下是可以实现的。然而,regexp的设计并不是为了进行有效的负匹配。 这些regexp很容易出错,而且很难读取

自版本2.0以来,Spark不支持“非rlike”

 # given 'url' is column on a dataframe
 df.filter("""url not rlike "stackoverflow.com"""")

我知道的唯一用法是sql字符串表达式(如上所述)。我在python api中找不到“not”sql dsl函数。scala中可能有一个。

在PySpark中实现这一点的简明方法是:

df.filter(~df.column.rlike(pattern))

你能否定你的正则表达式,只使用
rlike
而不是
not-rlike
?正如@doelleri所说,下一步要尝试的是
not(columnB-rlike'^[0-9]*$)
或类似的方法。(不知道括号是否可选。取决于语言。)我们的无名英雄!这应该是公认的答案,但很久以前就有人问:)