Spark SQL filter not contains

软件环境:CDH5.8.0;

问题:在使用Spark SQL 读取Hive进行操作的时候,需要使用不包含,如下:(在Spark SQL中有contains,like,rlike函数)

在Hive中有表id_url ,内容如下:

+------------+-----------------------------------+--+
| id_url.id  |            id_url.url             |
+------------+-----------------------------------+--+
| 1          | http://abc.com/ac/10987_2.html    |
| 2          | http://abc.com/ac/109872.html     |
| 3          | http://abc.com/ac/10987_4.html    |
| 4          | http://abc.com/ac/10987_30.html   |
| 14         | http://abc.com/ac/a10987_30.html  |
| 42         | http://abc.com/ac/c10987_30.html  |
| 43         | http://abc.com/ac/1d0987_30.html  |
+------------+-----------------------------------+--+

如果要查看url包含30的网页,可以使用:

假设已经有data数据:

scala> val data = sqlContext.sql("select * from fansy.id_url")
data: org.apache.spark.sql.DataFrame = [id: int, url: string]
那么可以使用contains或like货rlike,如下:

scala> data.filter(data("url") contains "30").collect.foreach(println(_))
[4,http://abc.com/ac/10987_30.html]                                             
[14,http://abc.com/ac/a10987_30.html]
[42,http://abc.com/ac/c10987_30.html]
[43,http://abc.com/ac/1d0987_30.html]

scala> data.filter(data("url") like "%30%").collect.foreach(println(_))
[4,http://abc.com/ac/10987_30.html]                                             
[14,http://abc.com/ac/a10987_30.html]
[42,http://abc.com/ac/c10987_30.html]
[43,http://abc.com/ac/1d0987_30.html]

scala> data.filter(data("url") rlike ".*30.*").collect.foreach(println(_))
[4,http://abc.com/ac/10987_30.html]                                             
[14,http://abc.com/ac/a10987_30.html]
[42,http://abc.com/ac/c10987_30.html]
[43,http://abc.com/ac/1d0987_30.html]
那如果是不包含呢?

1. 使用rlike的正则去匹配不包含30的字符串;

扫描二维码关注公众号,回复: 4005558 查看本文章

scala> data.filter(data("url") rlike "^((?!30).)*$").collect.foreach(println(_))
[1,http://abc.com/ac/10987_2.html]
[2,http://abc.com/ac/109872.html]
[3,http://abc.com/ac/10987_4.html]
但是,在大量字符串匹配的时候效率会非常低;

2. 使用not 或!

查看Column的API可以看到其还有一个函数,为not或!,通过这个函数可以把如contains/like/rlike等转换为反,如下:

scala> val t = not (data("url") contains "30")
t: org.apache.spark.sql.Column = NOT Contains(url, 30)

scala> val t1 = not (data("url") contains "30")
t1: org.apache.spark.sql.Column = NOT Contains(url, 30)
同时,使用t或t1进行filter,可以看到结果:

scala> data.filter(t).collect.foreach(println(_))
[1,http://abc.com/ac/10987_2.html]
[2,http://abc.com/ac/109872.html]
[3,http://abc.com/ac/10987_4.html]

scala> data.filter(t1).collect.foreach(println(_))
[1,http://abc.com/ac/10987_2.html]                                              
[2,http://abc.com/ac/109872.html]
[3,http://abc.com/ac/10987_4.html]

分享,成长,快乐

脚踏实地,专注

转载请注明blog地址:http://blog.csdn.NET/fansy1990


猜你喜欢

转载自blog.csdn.net/fansy1990/article/details/72666897