LIKE '%черги%' шукає підрядок: не знаходить інших форм слова, не ранжує результати й не використовує звичайні індекси. Повнотекстовий пошук працює зі словами.
Два типи:
tsvector- документ, розібраний на нормалізовані слова (лексеми) з позиціями;tsquery- запит з операторами&(і),|(або),!(не),<->(наступне слово).
SELECT to_tsvector('english', 'Running background jobs with queues');
-- 'background':2 'job':3 'queue':5 'run':1
SELECT to_tsvector('english', 'Running background jobs with queues')
@@ to_tsquery('english', 'queue & job'); -- true
Конфігурація (english) визначає словники: стемінг (jobs → job, running → run), стоп-слова (with викинуто), нижній регістр.
Зручні функції для запиту від користувача:
websearch_to_tsquery('english', 'laravel queues -redis "failed jobs"') -- синтаксис як у пошуковиках
plainto_tsquery('english', 'laravel queues') -- просто слова через «і»
Індекс - GIN за tsvector, найкраще збереженим у згенерованій колонці:
ALTER TABLE posts ADD COLUMN search tsvector
GENERATED ALWAYS AS (
setweight(to_tsvector('english', coalesce(title, '')), 'A') ||
setweight(to_tsvector('english', coalesce(body, '')), 'B')
) STORED;
CREATE INDEX posts_search_idx ON posts USING gin (search);
SELECT * FROM posts WHERE search @@ websearch_to_tsquery('english', 'queue retries');
Чого повнотекстовий пошук PostgreSQL не вміє з коробки: виправляти опечатки (для цього pg_trgm), шукати синоніми без налаштування словників, «пошук під час набору» за частиною слова (лише префікси: 'que:*'), складне ранжування з урахуванням популярності.
Для пошуку по сайту, документації, товарах середнього обсягу його часто достатньо - без окремого сервісу.