Postgres full-text search (tsvector/tsquery + index GIN) là đủ cho phần lớn ứng dụng vừa: tìm trong tiêu đề/mô tả, vài trăm nghìn tới vài triệu bản ghi, kết hợp WHERE với cột quan hệ khác.
sql
create index posts_fts_idx on posts
using gin (to_tsvector('simple', title || ' ' || body));
select id, title from posts
where to_tsvector('simple', title || ' ' || body) @@ plainto_tsquery('simple', $1)
order by created_at desc limit 20;Lợi thế lớn nhất: một nguồn sự thật, không có pipeline đồng bộ, không có độ trễ, join thẳng với dữ liệu quan hệ (lọc theo trạng thái, quyền, tồn kho ngay trong cùng câu truy vấn).
Chuyển sang Elasticsearch khi xuất hiện các nhu cầu Postgres làm được nhưng chật vật:
- Xếp hạng liên quan (relevance) là tính năng chính: boost theo trường, tuning điểm, chấm điểm theo nhiều tín hiệu.
ts_rankcủa Postgres rất cơ bản. - Fuzzy / typo tolerance, autocomplete, gợi ý ở quy mô lớn. Postgres có
pg_trgmnhưng chi phí tăng nhanh theo dữ liệu. - Facet / aggregation trên kết quả tìm kiếm (đếm theo hãng, khoảng giá) với độ trễ thấp.
- Phân tích ngôn ngữ nâng cao (stemming đa ngôn ngữ, synonym, phân tích tiếng Việt có dấu/không dấu).
- Traffic tìm kiếm lớn tới mức cần tách tải khỏi DB giao dịch.
Lộ trình thực dụng: bắt đầu bằng Postgres FTS, đo lại khi truy vấn tìm kiếm trở thành phần chậm nhất hoặc khi yêu cầu relevance vượt quá ts_rank, rồi mới thêm ES như một read model đồng bộ từ Postgres.