Хороший способ поиска похожих слов в PostgreSQL - PullRequest
0 голосов
/ 29 мая 2018

Я использую PostgreSQL 10 и, хотя у меня есть некоторый опыт написания запросов, я сейчас не особо разбираюсь в СУБД.Я хочу, чтобы мой запрос был более «интеллектуальным», а не просто соответствовал точным словам.Я сделал скромное исследование, и кажется, что для этого у нас есть много возможностей.Сначала я подумал об использовании RegEx в запросе, но это не очень хорошая идея, потому что RegEx довольно ограничены.Я уверен, что в Postgres есть более подходящая для этого функция.

Для реализации моего интеллектуального поиска у меня возникла такая идея: пользователь может забыть букву в каждом слове или повторять буквы, которые не будутвызвать несоответствие.Также должны совпадать буквы типа ç и c. Эта идея не является идеальным воспроизведением проблемы, которую я должен решить. Я только раскрываю свою проблему.

Например:

Если пользователь ищет "macs"vermelhas».Я должен вернуть результаты, содержащие "macas vermelhas", "maças vermelhas", "macs vermelhas", "macs vrmelhas".

Система на португальском языке, и у меня почти такие же проблемы с поиском испанского языка (ê, ü, ã и т. д.).

1 Ответ

0 голосов
/ 29 мая 2018

Я думаю, что индексы триграмм идеально вам подходят.

CREATE EXTENSION pg_trgm;

Давайте создадим такую ​​таблицу:

CREATE TABLE words (word text);

INSERT INTO words VALUES ('maças vermelhas');
INSERT INTO words VALUES ('alguna cosa');

CREATE INDEX ON words USING gin (word gin_trgm_ops);

Теперь вы можете найти слова по сходству:

SELECT * FROM words WHERE word % 'macs vermelhas';

      word       
-----------------
 maças vermelhas
(1 row)

Можно использовать индекс (в этом случае я принудительно):

SET enable_seqscan=off;

EXPLAIN (COSTS OFF)
   SELECT * FROM words WHERE word % 'macs vermelhas';

                     QUERY PLAN                      
-----------------------------------------------------
 Bitmap Heap Scan on words
   Recheck Cond: (word % 'macs vermelhas'::text)
   ->  Bitmap Index Scan on words_word_idx
         Index Cond: (word % 'macs vermelhas'::text)
(4 rows)
...