Tantivy 소개 — 스키마·인덱싱·검색 흐름

Tantivy 소개

Rust로 전체 텍스트 검색 엔진을 처음부터 만들기엔 부담이 크죠. Tantivy는 이를 라이브러리로 제공해서, Elasticsearch 같은 서버 대신 코드 안에서 곧바로 인덱스·검색을 구축하게 해줘요. 설계는 Lucene을 많이 닮았어요.

빠른 시작 코드

검색의 전체 흐름(스키마 → 인덱스 → 검색)을 한눈에 보여주는 예시예요.

let mut schema_builder = Schema::builder();
// TEXT: 토큰화·인덱싱 + term frequency/positions
// STORED: 행 단위 압축 저장소에도 보존 (검색 결과 문서 재구성용)
let title = schema_builder.add_text_field("title", TEXT | STORED);
let body = schema_builder.add_text_field("body", TEXT);
let schema = schema_builder.build();

let index = Index::create_in_dir(index_path, schema.clone())?;
// 100MB 버퍼를 인덱싱 스레드 간 분할
let mut index_writer: IndexWriter = index.writer(100_000_000)?;
index_writer.add_document(doc!(
    title => "The Old Man and the Sea",
    body => "He was an old man who fished alone in a skiff ..."
))?;
// 커밋해야 디스크에 flush되고 새 문서가 검색 가능해짐
index_writer.commit()?;

let reader = index.reader()?;
let searcher = reader.searcher();
let query_parser = QueryParser::for_index(&index, vec![title, body]);
let query = query_parser.parse_query("sea whale")?;
let top_docs: Vec<(Score, DocAddress)> =
    searcher.search(&query, &TopDocs::with_limit(10).order_by_score())?;

핵심 개념

  • Index — 세그먼트의 모음. 검색·인덱싱의 최상위 진입점
  • Segment — 인덱스 구조의 핵심 단위. 문서와 인덱스를 담고, 인덱싱·검색의 원자적 단위
  • Schema — 인덱스 필드 집합. 각 필드는 데이터 타입과 속성을 가져요
  • IndexWriter — 세그먼트 생성·병합 담당, 토큰화부터 저장까지 파이프라인 수행
  • SearcherQuery를 구현하는 어떤 것이든 세그먼트를 검색하고 결과 병합
  • Directory — 인덱스 데이터 저장소 추상화
  • Tokenizer — 텍스트를 토큰으로 분해

더 알아보기