Увійти Реєстрація
Блог Серії
Кар'єра
Вакансії Компанії
Навчання
Документація Співбесіди Тестування Відео
Екосистема
Пакети Ресурси Проєкти Інструменти Події
Інше
Про нас Реклама

Як працює повнотекстовий пошук у PostgreSQL?

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:*'), складне ранжування з урахуванням популярності.

Для пошуку по сайту, документації, товарах середнього обсягу його часто достатньо - без окремого сервісу.

Докладніше в документації: Повнотекстовий пошук

Схожі питання