2015-12-28 2 views
0

[PostgreSQL (9.4), Rails (4.1)]Нормализовать ищет значение в поисковом запросе SQL

Проблема:
У меня есть таблица с именами инструментов. column_name - это номер hstore и выглядит примерно так: name -> ('en': value, 'de': value). Стоит отметить, что «de» не является необходимым в этой проблеме, потому что все имена хранятся только в ключе «en».
Далее я должен построить поисковый запрос, который будет найти правильную запись, но формат текст в запросе неизвестен, например:

В БДЕ:
WQXZ 123GT, должны соответствовать запросу: WQXZ_123-GT

В БД:
Three Words Name 123-D45, должны соответствовать запрос: Three_WORDS_NAME 123D45

и так далее ...


Чтобы это произошло, я хочу нормализовать значение, которое я ищу, и запрос таким образом, чтобы оба они были идентичными. Для этого мне нужно сделать оба значения в downcase, удалить все whitspaces, удалить все не алфавитно-цифровые символы, поэтому указанные выше значения будут:
wqxz123gt == wqxz123gt и threewordsname123d45 == threewordsname123d45

У меня нет никаких проблем, чтобы форматировать значение поиска рубина: "sTR-in.g24 3".downcase.gsub(/\s/, "").gsub(/\W/, "") # => "string243" Но я не могу понять, как это сделать в SQL-поисковый запрос, чтобы выглядеть следующим образом:

Tool.where("CODE_I_AM_LOOKING_FOR(name -> 'en') = (?)", value.downcase.gsub(/\s/, "").gsub(/\W/, ""))

Спасибо за ваше время.

UPD: я могу сделать downcase в запросе:

Tool.where("lower(name -> 'en') = (?)", value.downcase)

Но это решает только часть проблемы (downcase). Белые пробелы и символы без слов (точки, тире, подчеркивания и т. Д.) По-прежнему остаются проблемой.

+0

'("? Имя -> 'ан' =", value.downcase.gsub (/ \ s /, "") .gsub (/ \ W/, "")) 'этот не выполняется? –

+0

Нет, потому что он «нормализует» только значение.Таким образом, «WQXZ_123-GT» станет «wqxz123gt», но это не повлияет на значение в БД - «WQXZ 123GT», потому что оно все равно будет таким же. – RedZagogulin

+0

'(" name -> 'en' =: value ", value: value)) –

ответ

1

Вы можете использовать функцию Postgres replace для удаления пробелов. Затем используйте функцию lower для соответствия этому значению. Как это.

Tool.where("lower(replace(name -> 'en', ' ', '')) = (?)", value.downcase.gsub(/\s/, "").gsub(/\W/, "")) 

Надеюсь, это было бы полезно.

0

Nitin Srivastava's Ответ направил меня в правильном направлении. Все, что мне было нужно, это использовать функцию regexp_replace.

Так собственно запрос:

Tool.where(
    "lower(regexp_replace((name -> 'en'), '[^a-zA-Z0-9]+', '', 'g')) = ?", 
    value.downcase.gsub(/\s/, "").gsub(/\W/,"") 
) 
Смежные вопросы