한양과학기술고등학교

에듀테크 프로젝트 대시보드

전문 검색

tsvector tsquery @@ ts_rank GIN 한국어

LIKE 로는 부족한 '자연어 검색' — 형태소·불용어·순위를 처리합니다.

1. 개념

SELECT to_tsvector('english', 'The quick brown foxes are running');
-- 'brown':3 'fox':4 'quick':2 'run':6   (어간 추출·불용어 제거됨)

SELECT to_tsvector('english', 'running foxes') @@ to_tsquery('english', 'fox & run');
-- true
함수용도
to_tsquery연산자 직접 (fox & run, cat | dog, !bird)
plainto_tsquery공백을 AND 로 (사용자 입력 안전)
websearch_to_tsquery구글식 ("exact", -exclude, or)

2. 컬럼 + 인덱스

ALTER TABLE articles ADD COLUMN search tsvector
  GENERATED ALWAYS AS (
    to_tsvector('english', coalesce(title,'') || ' ' || coalesce(body,''))
  ) STORED;

CREATE INDEX idx_articles_search ON articles USING gin (search);

3. 검색 + 순위

SELECT id, title,
       ts_rank(search, q) AS rank
FROM articles, websearch_to_tsquery('english', $1) q
WHERE search @@ q
ORDER BY rank DESC
LIMIT 20;

4. 한국어

내장 기능의 한계
  • PostgreSQL 기본 배포에는 한국어 형태소 분석기가 없음 (simple 설정은 공백 단위만)
  • 옵션: pg_bigm·pg_trgm(부분일치), mecab-ko 기반 textsearch_ko, 또는 Elasticsearch/Meilisearch 외부 검색엔진
  • 간단한 사이트 검색이면 pg_trgm + ILIKE '%키워드%' 로도 충분
"정규화로 시작하고, 측정한 뒤에 비정규화하라"