我如何在spark-sql中使用“not rlike”?

时间:2015-12-30 17:19:54

标签: 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 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")

或者是问题https://issues.apache.org/jira/browse/SPARK-4207的延续?

5 个答案:

答案 0 :(得分:3)

没有任何东西可以不是rlike,但在正则表达式中你有一些叫做负向前瞻的东西,这意味着它会给出不匹配的单词。

对于上述查询,您可以使用正则表达式,如下所示。可以说,你希望ColumnB不应该以数字' 0'

开头

然后你可以这样做。

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

我的意思是,你必须使用正则表达式自我否定匹配,而不是rlike。 Rlike只是匹配你要求匹配的正则表达式。如果你的正则表达式告诉它不匹配,它会应用它,如果你的正则表达式是匹配,那么它就是这样。

谢谢你, 问候, 作者Srini。

答案 1 :(得分:3)

我知道你的问题有点老了,但为了以防万一:你是否只是尝试了scala的一元"!"操作

在java中你可以这样:

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

答案 2 :(得分:2)

在PySpark中实现的一种简洁方法是:

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

答案 3 :(得分:0)

在pyspark中,我这样做是:

public class MyPagerAdapter extends FragmentStatePagerAdapter {

    private ArrayList<CrimeData> list;

    public MyPagerAdapter(FragmentManager fm, ArrayList<CrimeData> list) {
        super(fm);
        this.list = list;
    }

    @Override
    public Fragment getItem(int i) {
        CrimeData cd = list.get(i);
        Bundle b = new Bundle();
        b.putString("crimename",cd.getCrimeName());
        b.putString("crimedate",cd.getCrimeDate().toString());
        b.putBoolean("crimestatus",cd.isCrimeStatus());
        return CrimeFragment.newInstance(b);
    }

    @Override
    public int getCount() {
        return list.size();
    }
}

答案 4 :(得分:0)

以上答案建议使用负前瞻。在某些情况下可以实现。但是,正则表达式的设计并不是为了使负匹配有效。 那些正则表达式将易于出错并且难以阅读。

Spark从2.0版开始不支持“不喜欢”。

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

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