본 포스팅은 2025년 06월 12일을 기준으로 작성되었습니다.
검색 엔진을 개발하면서 가장 까다로웠던 부분 중 하나는 자동완성(Auto-complete) 기능이었습니다. 단순히 입력어를 기준으로 추천어를 보여주는 수준을 넘어, 다양한 검색 패턴을 수용하고 사용자 경험(UX)을 고려한 설계가 필요했기 때문입니다.
고려 요소
자동완성 기능 구현 시 고려했던 주요 요소는 다음과 같습니다:
자동완성 전용 인덱스 구성
초성 검색 대응
다양한 Analyzer 설정
Search Template 설계 및 정교한 쿼리 구성
1. 자동완성 인덱스 구성
초기 요구사항은 문서 내의 “데이터명”만 자동완성 대상으로 하자는 것이었습니다. 하지만 검색 UX 측면에서 키워드가 먼저 노출되는 방식이 더 직관적이라는 판단 하에, 다음과 같은 전처리 및 인덱스 설계를 진행했습니다:
문서를 복제하여 키워드 전용, 데이터명 전용 두 종류로 분리
데이터명에서 불필요한 접두어(예: (주), (재)) 제거 및 50자 초과 텍스트 정리
키워드는 콤마(,) 기준으로 분리해 각각 독립 문서로 저장
특수문자(_, @, # 등) 제거 및 공백 정리
transform을 이용해 중복 키워드 제거
최종적으로 키워드와 데이터명을 autocomplete 필드로 분리 등록하여 인덱스를 구성했습니다.
2. 초성 검색 대응
Elasticsearch에서 별도 플러그인 없이도 초성 검색이 가능한 방식은 다음과 같이 구성했습니다:
icu_normalizer를 통한 자모 분리
pattern_replace를 이용해 중성·종성 제거
keyword tokenizer 적용
lowercase, ngram filter로 변형 대응
이 설정을 통해 사용자가 초성만 입력해도 원하는 자동완성 결과를 제공할 수 있었습니다.
3. Analyzer 구성
데이터 정확도와 검색의 유연성을 높이기 위해 총 5개의 필드를 구성했습니다.
jaso_analyzer (Tokenizer: keyword) → 초성 대응
standard_analyzer (Tokenizer: standard) → 일반 검색
edge_ngram_analyzer (Tokenizer: standard) → 접두어 매칭
ngram_analyzer (Tokenizer: standard) → 부분 검색
keyword 필드 → 정확한 일치 검색
autocomplete 필드에는 위 5개의 서브필드를 적용하여 다양한 검색 패턴을 지원하도록 했습니다.
4. Search Template 구성
다양한 검색 시나리오를 수용하기 위해 Search Template에 아래 쿼리 조건과 Boost 전략을 설계했습니다:
각 조건의 역할과 Boost 값
🔹 match_phrase (boost: 10) → 입력한 초성이 정확히 순서대로 포함된 문장 검색
🔹 match on ngram (boost: 3) → 단어 일부만 일치해도 검색
🔹 match on edge_ngram (boost: 2) → 단어의 앞부분부터 일치하는 검색
🔹 term on keyword (boost: 10) → 완전히 일치하는 단어만 검색
🔹 term on ngram (boost: 7) → n-gram 조각 중 정확히 일치하는 경우 검색
🔹 prefix on standard (boost: 5) → 특정 단어로 시작하는 텍스트 검색
이 구조를 통해 사용자가 입력한 형태에 관계없이 유연한 자동완성 검색 결과를 제공할 수 있었습니다.
자동완성 기능은 단순히 Analyzer 몇 개를 구성하는 것을 넘어,
사용자 검색 패턴에 맞춘 인덱싱 전략
검색 정확도와 유연성 간 균형
운영 환경에 맞는 튜닝
이 모두를 고려해야 높은 품질의 결과를 제공할 수 있습니다.
본 아키텍처는 현재 운영 중인 환경에서 안정적으로 자동완성 기능을 제공하고 있으며, 추후에는 랭킹 알고리즘이나 사용자 행동 기반 추천 기능까지 확장할 계획입니다.