Чувствительность к регистру при сопоставлении строк dplyr + RPostgreSQL - PullRequest
0 голосов
/ 28 августа 2018

Я не могу понять, как применить не учитывающий регистр запрос фильтра к удаленной таблице PostgreSQL, используя dplyr. Для демонстрации:

require(dplyr)
require(stringr)
require(RPostgreSQL)

drv <- dbDriver("PostgreSQL")
con <- dbConnect(drv, dbname="mydb", host="localhost", port=5432, user="username")

# create db table
copy_to(con, iris, "iris", temporary = FALSE)

# dplyr remote database table
iris_pg <- tbl(con, "iris")

iris_pg %>% filter(str_detect(Species, 'setosa')) %>% head(3) %>% collect()
# A tibble: 3 x 5
  Sepal.Length Sepal.Width Petal.Length Petal.Width Species
*        <dbl>       <dbl>        <dbl>       <dbl> <chr>  
1          5.1         3.5          1.4         0.2 setosa 
2          4.9         3            1.4         0.2 setosa 
3          4.7         3.2          1.3         0.2 setosa

iris_pg %>% filter(str_detect(Species, 'Setosa')) %>% head(3) %>% collect()
# A tibble: 0 x 0

Чтобы игнорировать регистр stringr::fixed('Setosa', ignore_case=TRUE) работает с фильтрацией таблиц. Но с таблицей postgres это не имеет никакого эффекта:

iris_pg %>% filter(str_detect(Species, stringr::fixed('SETOSA', ignore_case=TRUE))) %>% head(3) %>% collect()
# A tibble: 0 x 0

Кто-нибудь знает об обходном пути?

1 Ответ

0 голосов
/ 28 августа 2018

Это не работает, потому что, как вы можете видеть здесь , при использовании бэкэнда PostgreSQL dbplyr полагается на чувствительную к регистру функцию STRPOS для перевода str_detect в SQL.

Некоторые возможные обходные пути:

1) filter(str_detect(tolower(myvar), tolower(pattern))), вероятно, работает с любой реляционной базой данных.

2) filter(myvar %~*% pattern) опирается на ~*, оператор PostgreSQL для нечувствительных к регистру регулярных выражений POSIX.

3) filter(myvar %ilike% paste0("%", pattern, "%")) опирается на ILIKE, регистрозависимую и специфичную для Postgres версию стандартного оператора LIKE.

...