[Intum Dev](https://intum.dev.md) / [Bazy Danych](https://intum.dev/bazy-danych.md)

# [Full Text Search i Vector DB w PostgreSQL i RDS](https://intum.dev/bazy-danych/full-text-search-i-vector-db-w-postgresql-i-rds.md)

## Wyszukiwanie w PostgreSQL — co mamy natywnie

PostgreSQL ma wbudowany full text search przez **GIN index + tsvector/tsquery**. Działa, ale ma ograniczenia:
- Ranking (ts_rank) jest podstawowy w porównaniu z BM25
- Brak typo tolerance i fuzzy match (do tego trzeba pg_trgm)
- Przy złożonych filtrach + sortowaniu po relevance — słaba wydajność
- Brak hybrid search (FTS + wektory w jednym zapytaniu)

Do prostego wyszukiwania w CRUD wystarcza. Przy bardziej wymagających scenariuszach potrzebne są rozszerzenia.

## Tantivy — silnik wyszukiwania w Rust

Tantivy to biblioteka (library) full text search napisana w Rust, inspirowana Apache Lucene. Sama w sobie nie jest produktem — to silnik, który inne narzędzia wbudowują w swoje rozwiązania:

| Produkt | Co robi z Tantivy |
|---|---|
| **ParadeDB (pg_search)** | Extension do PostgreSQL — BM25 search przez SQL |
| **Quickwit** | Search engine do logów (alternatywa Elasticsearch) |
| **Meilisearch** | Wyszukiwarka SaaS z typo tolerance |

Analogicznie: Lucene (Java) → Elasticsearch/Solr. Tantivy (Rust) → ParadeDB/Quickwit/Meilisearch.

## ParadeDB — Tantivy + pgvector w PostgreSQL

ParadeDB to dwa rozszerzenia PostgreSQL:
- **pg_search** — Tantivy (BM25, full text search)
- **pg_analytics** — DuckDB (columnar storage, analytics)

Można zainstalować samo `pg_search` bez reszty. Daje:

**Full text search:**
```sql
CREATE INDEX ON products USING bm25 (name, description);

SELECT * FROM products
WHERE name @@@ 'wireless headphones'
ORDER BY paradedb.score(id) DESC
LIMIT 10;
```

Operator `@@@` to BM25 search przez Tantivy — zamiennik standardowego `@@` z tsvector, ale szybszy i z lepszym rankingiem.

**Vector search** — obsługuje HNSW (jak pgvector) + hybrid search łączący BM25 i wektory w jednym zapytaniu.

**Czego nie ma (vs Elasticsearch):**
- Faceted search — ograniczony
- Agregacje/analytics — trzeba robić przez SQL
- Dashboard (jak Kibana) — nie ma
- Skalowanie na wiele nodów — ograniczone do tego co daje PostgreSQL

## Dostępność na AWS RDS

| Extension | RDS | Aurora | Od wersji PG |
|---|---|---|---|
| **pgvector** | tak | tak | 13+ |
| **pg_trgm** | tak | tak | wszystkie |
| **btree_gin** | tak | tak | wszystkie |
| **pg_search (ParadeDB)** | nie | nie | - |
| **ZomboDB** | nie | nie | - |

**ParadeDB nie jest dostępny na RDS/Aurora** — AWS ma ograniczoną listę wspieranych extensions.

## Architektura: RDS + własny PG z ParadeDB

Można postawić własny PostgreSQL z ParadeDB obok RDS i synchronizować dane przez **logical replication**:

```
RDS PostgreSQL (główna baza, CRUD)
    │
    │ logical replication
    ▼
EC2 PostgreSQL + ParadeDB (read-only, FTS + vector search)
```

### Konfiguracja

```sql
-- Na RDS (publisher) — wymaga rds.logical_replication = 1 (restart)
CREATE PUBLICATION search_pub FOR TABLE products, articles;

-- Na własnym PG z ParadeDB (subscriber)
CREATE SUBSCRIPTION search_sub
  CONNECTION 'host=rds-endpoint dbname=mydb user=repl'
  PUBLICATION search_pub;
```

### Jak to działa
- Replikuje INSERT/UPDATE/DELETE w czasie rzeczywistym (opóźnienie <1 sekundy)
- Nie replikuje DDL (CREATE TABLE, ALTER) — trzeba zarządzać ręcznie
- Parametr `rds.logical_replication` musi być włączony na RDS (wymaga restart instancji)
- Aplikacja pisze do RDS, czyta normalny CRUD z RDS, a wyszukiwanie odpytuje ParadeDB PG

### Alternatywy synchronizacji
- **AWS DMS** — managed replication, ale dodatkowy serwis
- **Debezium (CDC)** — Change Data Capture z WAL-a, najbardziej elastyczne ale ciężkie operacyjnie

## Porównanie podejść do wyszukiwania z PostgreSQL

| Podejście | FTS | Vector search | Złożoność | Koszt |
|---|---|---|---|---|
| **Natywny PG** (GIN + tsvector) | podstawowy | nie | zerowa | brak |
| **PG + pgvector** | podstawowy | tak (HNSW) | niska | brak |
| **PG + ParadeDB** | BM25 (jak ES) | tak (hybrid) | średnia | wymaga własnego PG |
| **PG + Elasticsearch/OpenSearch** | pełny | tak (kNN) | wysoka | osobny klaster |
| **PG + Meilisearch** | pełny + typo tolerance | tak | średnia | osobny serwis |

## Rekomendacja

- **Prosty CRUD** — natywny GIN + tsvector + pg_trgm wystarczy
- **CRUD + semantic search/RAG** — pgvector (dostępny na RDS)
- **Zaawansowany FTS bez opuszczania PostgreSQL** — ParadeDB na własnym PG z logical replication z RDS
- **Pełna wyszukiwarka z facetami i autocomplete** — Meilisearch lub Elasticsearch jako osobny serwis