Как выполнить SQL-запрос для слов с пунктуацией в Postgresql? - PullRequest
7 голосов
/ 18 марта 2011

Если у меня есть подобные строки / фразы, которые хранятся в базе данных:

  • Что такое операции типа Q?
  • Руководство программиста
  • A.B.C's Coding

Есть ли способ передать параметр запроса, например "Programmers" или "abc" или "q-type", и найти его "Programmer's", "A.B.C" и "Q-type"?

Ответы [ 6 ]

6 голосов
/ 18 марта 2011

tsvector

Используйте тип tsvector, который является частью функции текстового поиска PostgreSQL.

postgres> select 'What are Q-type Operations?'::tsvector;
              tsvector               
-------------------------------------
 'Operations?' 'Q-type' 'What' 'are'
(1 row)

Вы также можете использовать знакомые операторы в tsvector:

postgres> select 'What are Q-type Operations?'::tsvector
postgres>        || 'A.B.C''s of Coding'::tsvector;
                           ?column?                           
--------------------------------------------------------------
 'A.B.C''s' 'Coding' 'Operations?' 'Q-type' 'What' 'are' 'of'

Из документации tsvector:

Значение tsvector представляет собой отсортированный список различных лексем, которые являются словами, которые были нормализованы для объединения различных вариантов одного и того жеслово (подробности см. в главе 12).Сортировка и удаление дубликатов выполняются автоматически во время ввода

Если вы также хотите выполнить нормализацию для конкретного языка, например удалить общие слова ('the', 'a' и т. Д.) И умножения, используйтеto_tsvector функция.Он также присваивает веса различным словам для текстового поиска:

postgres> select to_tsvector('english',
postgres> 'What are Q-type Operations? A.B.C''s of Coding');
                      to_tsvector                       
--------------------------------------------------------
 'a.b.c':7 'code':10 'oper':6 'q':4 'q-type':3 'type':5
(1 row)

Полноценный текстовый поиск

Очевидно, что делать это для каждой строки в запросе будет дорого - поэтому вы должны сохранитьtsvector в отдельном столбце и используйте ts_query () для его поиска.Это также позволяет вам создавать индекс GiST для цветографа.

postgres> insert into text (phrase, tsvec)
postgres>   values('What are Q-type Operations?',
postgres>   to_tsvector('english', 'What are Q-type Operations?'));
INSERT 0 1

Поиск выполняется с использованием tsquery и оператора @@:

postgres> select phrase from text where tsvec @@ to_tsquery('q-type');
           phrase            
-----------------------------
 What are Q-type Operations?
(1 row)
2 голосов
/ 18 марта 2011

Вы можете попробовать использовать ILIKE с функцией перевода, см. здесь .

Например: translate(field, '.-\'', '')

1 голос
/ 18 марта 2011

Вот еще одна ссылка, которая может иметь отношение.Уберите значение поля из всех знаков препинания, прежде чем сравнивать его со строкой поиска.

SQL Server: Как удалить пунктуацию из поля?

0 голосов
/ 18 марта 2011

Postgresql поддерживает полнотекстовый поиск, конвертируя ввод текста в tsvector типы:

steve@steve@[local] =# select input, to_tsvector('english', input)\
   from (values('What are Q-type Operations?'),('Programmer''s Guide'),('A.B.C''s of Coding')) x(input);
            input            |            to_tsvector             
-----------------------------+------------------------------------
 What are Q-type Operations? | 'oper':6 'q':4 'q-type':3 'type':5
 Programmer's Guide          | 'guid':3 'programm':1
 A.B.C's of Coding           | 'a.b.c':1 'code':4
(3 rows)

Как вы видите, используемый по умолчанию ствол делает «программирование» «программистом» и «программистом»все совпадают одинаково.

Обычно вы используете это, имея индексированный столбец или выражение tsvector, а затем используете оператор @@, чтобы сопоставить это с tsquery, например:

steve@steve@[local] =# select input, to_tsvector('english', input) \
   from (values('What are Q-type Operations?'),('Programmer''s Guide'),('A.B.C''s of Coding')) x(input)\
   where to_tsvector('english', input) @@ plainto_tsquery('english', 'programmers');
       input        |      to_tsvector      
--------------------+-----------------------
 Programmer's Guide | 'guid':3 'programm':1
(1 row)

Здесь plainto_tsquery анализирует пользовательскую строку ввода и создает запрос, в котором каждому неостопному слову в запросе должен соответствовать цветатор.

0 голосов
/ 18 марта 2011

Postgres поддерживает сопоставление с образцом, поэтому вы можете создать регулярное выражение в предложении where http://www.postgresql.org/docs/8.3/static/functions-matching.html

0 голосов
/ 18 марта 2011

Звучит так, будто вы хотите что-то вроде этого:

http://www.postgresql.org/docs/9.0/static/fuzzystrmatch.html

Я не уверен на 100%, охватит ли это то, что вы хотите.

РЕДАКТИРОВАТЬ Я должен был запустить это локально, чтобы проверить (Использование PostgreSQL 9.0 в Windows)

Вот что я нашел:

template1=> select soundex('Programmers'), soundex('Programmer''s');
 soundex | soundex
---------+---------
 P626    | P626
(1 row)


template1=> select soundex('abc'), soundex('A.B.C.');
 soundex | soundex
---------+---------
 A120    | A120
(1 row)


template1=> select soundex('Q-type'), soundex('q-type');
 soundex | soundex
---------+---------
 Q310    | Q310
(1 row)

Так что если вы должны были сделать soundex(colname) = soundex(<user param>), вы должны получить то, что вам нужно в предложении where.

Вам потребуется установить модуль fuzzystrmatch :

psql -U <dbowner> -d <database> -f SHAREDIR/contrib/fuzzystrmatch.sql

Обратитесь к документации о том, как найти SHAREDIR

РЕДАКТИРОВАТЬ Я только что заметил, что упустил из виду, я думаю, что это в сочетании с функциональностью ts_vector может привести вас к тому, к чему вы стремитесь.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...