DBAtlas · 데이터베이스 운영 아틀라스

전문 검색(Full-text search)

Oracle

-- Oracle Text: create a CONTEXT index
CREATE INDEX article_idx ON article(content) INDEXTYPE IS CTXSYS.CONTEXT;
-- Search with CONTAINS (label 1 ties CONTAINS to SCORE):
SELECT id, SCORE(1) FROM article
WHERE CONTAINS(content, 'database AND performance', 1) > 0
ORDER BY SCORE(1) DESC;

Oracle Text(이전 interMedia)는 CONTEXT 인덱스를 통해 언어 인식 전문 검색을 제공한다. CONTAINS 연산자는 AND/OR/NEAR 같은 검색 연산자를 지원한다. 인덱스는 CTX_DDL.SYNC_INDEX 또는 자동 SYNC로 유지한다.

PostgreSQL

-- Search with tsvector/tsquery, accelerated by a GIN index:
CREATE INDEX article_fts_idx ON article
  USING GIN (to_tsvector('english', content));
SELECT id, ts_rank(to_tsvector('english', content), q) AS score
FROM article, to_tsquery('english', 'database & performance') q
WHERE to_tsvector('english', content) @@ q
ORDER BY score DESC;

PostgreSQL 내장 전문 검색은 @@ 연산자로 tsvector(문서)와 tsquery(쿼리)를 매칭한다. GIN 인덱스는 대용량 텍스트 검색 속도를 높인다. 언어 구성('english')이 어간 추출과 불용어 처리를 수행한다.

MySQL

-- Create a FULLTEXT index (InnoDB/MyISAM):
ALTER TABLE article ADD FULLTEXT INDEX ft_content (content);
-- Search in natural language / boolean mode:
SELECT id, MATCH(content) AGAINST('database performance') AS score
FROM article
WHERE MATCH(content) AGAINST('+database +performance' IN BOOLEAN MODE);

MySQL FULLTEXT 인덱스는 MATCH ... AGAINST 구문으로 조회한다. IN NATURAL LANGUAGE MODE는 관련도 점수를 반환하고, IN BOOLEAN MODE는 +/-/* 연산자로 세밀하게 제어한다. InnoDB는 5.6부터 전문 검색을 지원한다.

SQL Server

-- Create a Full-Text Catalog and index:
CREATE FULLTEXT CATALOG ft_catalog;
CREATE FULLTEXT INDEX ON dbo.article(content)
  KEY INDEX PK_article ON ft_catalog;
-- Search with CONTAINS / FREETEXT:
SELECT id FROM dbo.article
WHERE CONTAINS(content, '"database" AND "performance"');

SQL Server Full-Text Search는 먼저 Full-Text Catalog가 필요하고, 그다음 테이블에 Full-Text Index를 만든다(unique KEY INDEX 필수). CONTAINS는 정확/근접 검색과 논리 연산자를, FREETEXT는 의미 기반(언어학적) 검색을 지원한다. Full-Text Search 구성 요소가 설치되어 있어야 한다.

MongoDB

// Create a text index:
db.article.createIndex({ content: "text" })
// Search with $text and sort by relevance score:
db.article.find(
  { $text: { $search: "database performance" } },
  { score: { $meta: "textScore" } }
).sort({ score: { $meta: "textScore" } })

MongoDB text 인덱스는 $text 연산자로 전문 검색을 제공하며, 컬렉션당 text 인덱스는 하나만 가질 수 있다. textScore 메타 필드가 관련도를 보여 준다. 고급 검색에는 Atlas Search($search, Lucene 기반)를 사용한다.

Redis

# Requires the RediSearch module (Redis Stack).
# Define the index:
FT.CREATE article_idx ON HASH PREFIX 1 article: SCHEMA content TEXT
# Full-text search:
FT.SEARCH article_idx "database performance"

기본 Redis는 전문 검색을 제공하지 않는다. RediSearch 모듈(Redis Stack에 포함)이 FT.CREATE로 인덱싱을, FT.SEARCH로 검색을 제공한다. 어간 추출, fuzzy 검색, 필터링, 정렬을 지원한다. 모듈이 설치되어 있지 않으면 이 기능을 사용할 수 없다.

Elasticsearch

# Elasticsearch is natively a full-text search engine.
# match query (analyzed text search):
GET article/_search
{
  "query": {
    "match": { "content": "database performance" }
  }
}

Elasticsearch는 본질적으로 Lucene 기반 전문 검색 엔진이며, text 필드는 색인 시점에 분석된다(토큰화, 어간 추출). match 쿼리는 관련도 점수(_score) 순으로 정렬된 결과를 반환한다. 언어별 analyzer(예: 'english')를 지정할 수 있다.

DBAtlas에서 열기 →