정의
블로그·문서 검색창처럼 "이 단어가 들어간 글 목록"을 빠르게 뽑고 싶을 때 쓰는 자료구조다. 미리 "어떤 단어가 어느 문서들에 나오는지" 표를 만들어두면, 검색할 때 문서를 전부 뒤지지 않고 그 표만 보면 된다.
용어를 풀면, 토큰(token) 은 문서를 검색 단위로 쪼갠 조각(보통 단어 하나), 역색인(inverted index) 은 "토큰 → 그 토큰을 포함한 문서 목록" 방향의 매핑이다. 원래 문서는 "문서 → 그 안의 단어들" 순서인데 이걸 거꾸로(inverted) 뒤집었다는 뜻이다. 전문 검색(full-text search)은 이 역색인을 미리 만들어 질의를 빠르게 처리하는 기법이고, 그 역색인을 프로세스 메모리에 통째로 올려 쓰는 것이 인메모리 검색이다.
왜 필요한가
문서 전체를 매번 순회하며 부분 문자열을 찾으면 문서 수 N과 질의 길이에 비례해 느려지고, 랭킹·오타 허용·접두어 매칭을 직접 구현해야 한다. 역색인은 이를 사전 계산된 자료구조로 옮겨 검색 시점 비용을 줄인다. 상주 검색 서버를 두기 어려운 환경에서는 사전 빌드한 인덱스를 메모리에 올려 동일한 탐색 품질을 가볍게 제공할 수 있다.
동작 원리
- 색인 단계: 각 문서를 토큰화(단어 단위로 쪼개기)하고, 토큰별로 등장 문서 id 목록(posting list — 한 토큰이 나오는 문서들의 명단)을 만든다.
- 질의 단계: 검색어를 같은 방식으로 토큰화하고, 각 토큰의 posting list를 교집합/합집합해 후보 문서를 모은다.
- 랭킹: 필드 가중치(제목 > 태그 > 본문), TF(term frequency — 한 문서 안에서 그 단어가 몇 번 나오는지), 근접도(검색어들이 서로 얼마나 붙어 있는지) 등으로 후보를 점수화해 정렬한다.
- prefix/fuzzy 매칭: prefix(접두어 — "app"으로 "apple"까지 매칭)와 fuzzy(편집거리 기반 근사 매칭 — 오타 몇 글자를 허용)로 부분 입력과 오타를 흡수한다.
실무 적용
색인은 빌드 산출물로 고정해 런타임 생성 비용을 없애고, warm 인스턴스에서는 싱글톤으로 재사용한다.
트레이드오프
인메모리 라이브러리형은 외부 호스팅 없이 가볍고 배포가 단순하지만, 문서 수가 많아지면 메모리·로드 시간이 늘고 CJK 형태소 분석 같은 고급 처리에 약하다. 상주형 검색 엔진은 언어별 파이프라인·대규모·증분 갱신에 강하지만 별도 프로세스·호스팅 비용이 든다.
사용하면 안 되는 경우
수십만~수백만 문서, 복잡한 필터·패싯·언어별 형태소 품질이 핵심이면 인메모리 라이브러리형은 부적합하다. 이때는 상주형 검색 엔진을 쓴다. 또 자주 바뀌는 문서를 실시간 증분 색인해야 하면 빌드타임 고정 인덱스는 맞지 않는다.
흔한 실수
- 공백 기반 토크나이저로 CJK 텍스트를 색인해 한국어 검색 품질이 떨어짐.
- 모든 필드를 같은 가중치로 둬서 제목 일치가 본문 일치에 묻힘.
- 인덱스를 요청마다 새로 빌드해 콜드 스타트·지연을 키움(싱글톤 미사용).
관련 개념
- serverless-stateless-execution — 상주 엔진을 못 올릴 때 라이브러리형 인덱스를 함수 안에서 쓰는 배경.