Indexium/docs/adr/003-search-engine.md

33 lines
3.1 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# ADR-003: Использование PostgreSQL FTS и pg_trgm вместо Meilisearch/Elasticsearch
Дата: 2026-09-06
Статус: Принято
## Контекст
Для поиска модов по названию, описанию и авторам требуется полнотекстовый поиск и устойчивость к опечаткам (fuzzy search). Введение отдельного движка поиска (Meilisearch, OpenSearch, Elasticsearch) усложняет инфраструктуру и увеличивает потребление RAM (ещё один сервис в `docker-compose`, отдельный индекс, синхронизация).
На MVP ожидается <50k модов, поисковый трафик <100 RPS, VPS за $5–10.
## Решение
Использовать возможности PostgreSQL 16:
- `tsvector` + `GIN`-индексы для ранжированного полнотекстового поиска (`to_tsvector`, `ts_rank`, `plainto_tsquery`).
- Расширение `pg_trgm` для поиска с опечатками (Trigram Similarity, оператор `%`, `similarity()`).
- Материализованный `search_vector` с триггером на `INSERT/UPDATE` (см. `docs/database-schema.md`).
Запрос: `search_vector @@ plainto_tsquery` + фильтр по `mod_versions` (`GIN (game_versions, loaders)`) + `ORDER BY ts_rank DESC` + fallback `similarity()` при 0 результатах.
## Последствия
- **Плюсы:** Нет дополнительных сервисов в `docker-compose`, экономия памяти (~0 доп. RAM vs +500MB–1GB у Meilisearch), атомарные транзакции при обновлении индекса (нет лагосинка), проще бэкапы.
- **Минусы:** При объёме >500k записей или >500 RPS скорость FTS в Postgres начинает уступать специализированным движкам (latency >100ms, нет typo-tolerance из коробки как в Meilisearch).
- **План миграции:** Если p95 latency поиска превысит 100ms (метрика в `tracing` + Grafana), вынести индекс в Meilisearch: добавить воркер-синк `mods` → Meilisearch, переключить `GET /mods` на Meilisearch с fallback на Postgres. Схема БД не меняется.
## Альтернативы (отклонены на MVP)
- **Meilisearch** - отличный typo-tolerance, но +1 сервис, нужен отдельный деплой и синк.
- **Elasticsearch / OpenSearch** - оверхед по RAM/диску, нужен кластер даже для малого объёма.
- **SQLite FTS** - не подходит, уже Postgres как основной.
## Ссылки
- `docs/database-schema.md` - секция 2 (триггер `mods_search_vector_update`), секция 3 (примеры FTS + fuzzy).
- `docs/architecture.md` - секция 4 (Поиск без Elasticsearch).