1.4 KiB
ADR-0012: PostgreSQL full-text search before a dedicated search engine
- Status: Accepted
- Date: 2026-08-11
Context
Search is a headline feature of a storefront, and reaching for Elasticsearch or OpenSearch is the reflex. It is also a second datastore to run, secure, back up and keep in sync — for a catalog that starts at a few hundred products.
Decision
Start with PostgreSQL full-text search plus pg_trgm for fuzzy matching and typo
tolerance, behind a SearchProvider interface owned by SearchModule. The module is marked
EXTRACTION CANDIDATE and reads the catalog only through public services, so it holds no
privileged coupling.
Consequences
One datastore, no sync pipeline, no index drift, and search results that are transactionally consistent with the catalog. This is genuinely adequate below roughly 50k products with straightforward faceting.
The limits are known and will eventually bind: no relevance tuning to speak of, no learning-to-rank, weak multilingual analysis for Vietnamese. When they do, the provider interface is the seam — swapping in OpenSearch changes one implementation, not every listing page.
Alternatives considered
Elasticsearch/OpenSearch from day one — rejected as premature infrastructure. A hosted service (Algolia, Typesense Cloud) — a reasonable future option; deferred because it adds per-record cost and a sync pipeline before there is a search-quality problem to solve.