전문 검색(Full-Text Search, FTS)은 문서 내용 전체를 검색하는 기술이다. 단순한 LIKE 검색과 달리, 형태소 분석, 불용어 제거, 어간 추출, 관련성 순위를 지원하여 자연스러운 텍스트 검색을 가능하게 한다.
LIKE vs 전문 검색
sql
-- LIKE: 인덱스 사용 불가, 단순 패턴 매칭
SELECT * FROM articles WHERE content LIKE '%데이터베이스%';
-- 문제: 느림, "데이터베이스들" 또는 "DB" 매칭 불가
-- 전문 검색: 형태소 분석, 인덱스 활용
SELECT * FROM articles WHERE to_tsvector('korean', content) @@ to_tsquery('데이터베이스');
-- 장점: 빠름, 어간 매칭, 관련성 점수 산출
sql
-- FTS 컬럼과 인덱스 추가
ALTER TABLE articles ADD COLUMN search_vector tsvector;
UPDATE articles SET search_vector =
to_tsvector('english', coalesce(title,'') || ' ' || coalesce(content,''));
CREATE INDEX idx_fts ON articles USING GIN(search_vector);
-- 자동 업데이트 트리거
CREATE TRIGGER tsvector_update
BEFORE INSERT OR UPDATE ON articles
FOR EACH ROW EXECUTE FUNCTION
tsvector_update_trigger(search_vector, 'pg_catalog.english', title, content);
-- 검색 쿼리
SELECT title, ts_rank(search_vector, query) AS rank
FROM articles, to_tsquery('english', 'database & optimization') query
WHERE search_vector @@ query
ORDER BY rank DESC
LIMIT 10;
Elasticsearch 전문 검색
json
PUT /articles
{
"mappings": {
"properties": {
"title": {"type": "text", "analyzer": "korean"},
"content": {"type": "text", "analyzer": "korean"}
}
}
}
GET /articles/_search
{
"query": {
"multi_match": {
"query": "데이터베이스 최적화",
"fields": ["title^2", "content"],
"type": "best_fields"
}
},
"highlight": {
"fields": {"content": {}}
}
}
주요 개념
| 개념 | 설명 |
|---|
| 토큰화 | 텍스트를 단어 단위로 분리 |
| 불용어(Stopwords) | "이", "그", "a", "the" 등 제거 |
| 어간 추출(Stemming) | "running" → "run" |
| 역색인(Inverted Index) | 단어 → 문서 목록 매핑 |
| TF-IDF | 단어 빈도 × 역문서 빈도로 관련성 산출 |
| BM25 | TF-IDF 개선판, Elasticsearch 기본 |
관련 개념