제1편 | Elasticsearch 기본 개념 및 RDB 비교
제2편 | nori 분석기로 한국어 인덱스 구축하기
제3편 | RAG를 위한 다양한 검색 쿼리 실습
제4편 | 임베딩 모델을 활용한 Hybrid Search
제5편 | LangChain으로 RAG 구현하기
검색 시스템을 구축할 때 가장 중요한 요소 중 하나는 언어의 특성을 이해한 인덱싱 전략이다. 특히 영어 중심으로 설계된 많은 검색 기술을 한국어 환경에 그대로 적용하면 기대한 검색 품질을 얻기 어렵다. 영어는 단어 경계가 공백으로 명확히 구분되는 반면, 한국어는 조사와 어미가 결합된 형태로 표현되는 교착어이기 때문이다. 예를 들어 “사무실”, “사무실에서”, “사무실의”, “사무실로”와 같은 표현은 의미적으로 같은 단어를 기반으로 하지만 표면적으로는 서로 다른 문자열로 나타난다. 이러한 특성 때문에 단순한 문자열 기반 검색이나 공백 기준 토큰 분리만으로는 정확한 검색 결과를 제공하기 어렵다.
Elasticsearch 역시 기본적으로는 영어 중심의 분석기를 기반으로 설계되어 있기 때문에, 한국어 데이터를 제대로 검색하기 위해서는 형태소 분석 기반의 언어 처리 과정이 필요하다. Elasticsearch에서는 이를 위해 nori 분석기를 제공한다. nori는 한국어 형태소 분석을 기반으로 문장을 단어 단위로 분해하고, 조사나 어미와 같은 불필요한 요소를 제거하여 검색에 적합한 토큰을 생성한다. 이를 통해 사용자가 입력한 검색어와 문서의 의미적 일치를 보다 정확하게 판단할 수 있으며, 검색 품질 역시 크게 향상된다.
최근에는 전통적인 검색 시스템뿐만 아니라 AI 기반 검색과 RAG(Retrieval-Augmented Generation) 아키텍처에서도 이러한 언어 분석 과정의 중요성이 더욱 커지고 있다. 대형 언어모델(LLM)을 활용한 지식 검색 시스템에서도 결국 가장 먼저 수행되는 단계는 적절한 문서를 찾는 검색 과정이며, 이 단계의 품질이 전체 시스템의 성능을 좌우한다. 특히 한국어 데이터를 대상으로 하는 AI 서비스에서는 단순한 키워드 매칭이 아니라 형태소 기반의 정확한 인덱싱과 검색 구조가 필수적인 요소로 자리 잡고 있다.
이러한 배경에서 제2편에서는 Elasticsearch에서 한국어 데이터를 효과적으로 처리하기 위한 nori 분석기의 구조와 활용 방법을 살펴본다. 먼저 한국어 형태소 분석이 검색 품질에 어떤 영향을 미치는지 이해하고, 이어서 nori 분석기를 설치하고 인덱스에 적용하는 방법을 단계적으로 설명한다. 또한 실제 예제를 통해 nori 분석기가 어떤 방식으로 문장을 토큰화하고, 그 결과가 검색 쿼리와 어떻게 연결되는지를 확인할 것이다. 이를 통해 독자들은 한국어 검색 시스템을 구축할 때 반드시 고려해야 할 언어 분석 전략과 인덱스 설계 방법을 실무 관점에서 이해할 수 있을 것이다.
(이광수 '무정'을 예제로 한 RAG용 데이터베이스 생성)
제1편에서는 Elasticsearch의 기본 개요를 설명했습니다. 이번 편에서는 이광수의 고전 소설 '무정'(무료 텍스트 사용 가능)의 Elasticsearch 인덱스(데이터베이스)를 생성하고 검색이 가능해질 때까지를 해설합니다.
� '무정'(1917)은 이광수가 쓴 한국 최초의 현대 장편소설로, 공개 도메인 텍스트로 활용할 수 있습니다. 예제 텍스트 대신 자신만의 한국어 문서로 대체해도 됩니다.
파일출처 : https://gongu.copyright.or.kr/gongu/wrt/wrt/view.do?wrtSn=9079891&menuNo=200026
RAG에서 사용하는 검색 엔진에는 몇 가지 선택지가 있습니다.
Elasticsearch에서는 RAG 검색에 필요한 기능이 모두 하나로 통합되어 있어 환경 구축이 편리합니다.
한국어 형태소 분석을 위해 nori 플러그인이 포함된 Dockerfile을 작성합니다.
1. Dockerfile 생성과 과 기존 docker-compose.yml 파일을 수정합니다. (동일 폴더에 배치)
(1) Dockerfile 생성
# Dockerfile
FROM docker.elastic.co/elasticsearch/elasticsearch:8.18.0
RUN bin/elasticsearch-plugin install analysis-nori
(2) docker-compose.yml 수정
변경전
services:
elasticsearch:
image: docker.elastic.co/elasticsearch/elasticsearch:8.18.0
변경후 (image: → build: .)
services:
elasticsearch:
build: .
build: . 의미: 현재 폴더의 Dockerfile을 사용해 이미지 빌드
(3) 재실행
$ docker compose down
$ docker compose build
$ docker compose up -d
(4) 구동 및 설치 확인
$ curl localhost:9200/_cat/plugins?v
nori는 Elasticsearch에서 공식적으로 지원하는 한국어 형태소 분석 플러그인입니다. 일본어의 kuromoji에 해당하는 한국어 전용 어날라이저입니다.
nori 어날라이저의 주요 구성 요소
nori_tokenizer의 decompound_mode
nori_tokenizer는 복합어 처리 방식을 decompound_mode로 지정할 수 있습니다.
� RAG용 검색에는 'mixed' 모드가 권장됩니다. 복합어 전체와 개별 형태소 모두로 검색할 수 있어 재현율(Recall)이 높아집니다.
elasticsearch-dsl을 활용하여 인덱스를 생성합니다. 다음 Python 스크립트를 실행해 보세요.
파일명은 main1.py.
아래는 (1) 인덱스 생성 JSON을 명확히 만들고, (2) bulk 액션 포맷을 맞춘 예시입니다.
from tqdm import tqdm
from elasticsearch import Elasticsearch
from elasticsearch.helpers import bulk
INDEX_NAME = "mujung"
TEXT_DATA_PATH = "mujung.txt"
es = Elasticsearch("http://localhost:9200", request_timeout=20)
# 1) 인덱스 재생성
지금 바로 작가의 멤버십 구독자가 되어
멤버십 특별 연재 콘텐츠를 모두 만나 보세요.
오직 멤버십 구독자만 볼 수 있는,
이 작가의 특별 연재 콘텐츠