콘텐츠로 이동

Elasticsearch 토큰화

Elasticsearch 한국어 토큰화에 바른 적용하기

Elasticsearch에서 한국어 검색 품질은 토큰화(analyzer) 에 달려 있습니다. 기본 내장 분석기인 nori는 빠르지만 신조어·고유명사·복합명사에서 오분석이 잦습니다. 바른의 형태소 분석을 색인 전처리 단계에 두면, 더 정확한 토큰으로 색인해 검색 정확도를 높일 수 있습니다.

문제 상황

  • nori는 사용자 사전 관리가 까다롭고, 새 고유명사가 등장할 때마다 노드 재시작이 필요한 경우가 많습니다.
  • 걸어서세계속으로 같은 프로그램명이 엉뚱하게 쪼개져 검색에 걸리지 않습니다.
  • 띄어쓰기가 흐트러진 문서(아름다운강산)는 토큰 경계가 어긋납니다.

바른을 어떻게 적용하나

색인 파이프라인에서 문서 본문을 바른으로 먼저 분석해 형태소 토큰 배열을 만들고, 이를 whitespace 또는 keyword 분석기로 그대로 색인합니다. 바른의 사용자 사전과 띄어쓰기 보정(auto_spacing)을 활용하면 nori보다 운영이 단순합니다.

graph TD
  DOC[원문 문서] --> BAREUN[바른 형태소 분석];
  BAREUN --> NORM[명사·용언 원형 토큰];
  NORM --> ES[Elasticsearch 색인];
  Q[검색 질의] --> BAREUN2[바른 분석];
  BAREUN2 --> ES;

색인 토큰과 질의 토큰을 동일한 바른 분석기로 만들면, 색인-검색 양쪽의 토큰 기준이 일치해 매칭이 안정적입니다.

from bareunpy import Tagger

tagger = Tagger("koba-XXXX-...", "localhost")

def to_tokens(text: str):
    """본문을 색인용 토큰 배열로 변환합니다(명사 + 용언/형용사 원형)."""
    res = tagger.tags([text])
    tokens = res.nouns()                 # 체언
    for morph, tag in res.pos():
        if tag in ("VV", "VA"):          # 동사·형용사 원형도 색인
            tokens.append(morph)
    return tokens

print(to_tokens("걸어서세계속으로 다시 방송됩니다."))
['걸어서세계속으로', '방송', '걷', '되']

걸어서세계속으로사용자 사전의 고유명사 사전에 등록해 두면 하나의 토큰으로 유지됩니다.

결과와 이점

항목 nori 바른 적용
고유명사·신조어 사전 관리 번거로움 사용자 사전 실시간 갱신
복합명사 과분해 잦음 등재 시 유지 또는 의도대로 분해
띄어쓰기 오류 토큰 경계 어긋남 auto_spacing 보정 후 토큰화
정확도 보통 품사 태깅 99.6%

운영 팁

바른 사용자 사전은 파일 변경을 실시간으로 감지해 반영하므로, 사전을 바꿔도 서버 재시작이 필요 없습니다. 새 고유명사를 자주 추가하는 검색 서비스에 잘 맞습니다.

자주 묻는 질문

Q. nori를 완전히 대체해야 하나요?

상황에 따라 다릅니다. 정확도가 중요한 핵심 필드만 바른으로 전처리해 색인하고, 나머지는 nori를 쓰는 혼합 구성도 가능합니다.

Q. 색인과 검색 토큰 기준을 어떻게 맞추나요?

색인 시와 검색 시 같은 사용자 사전·같은 옵션으로 바른을 호출하면 됩니다. 질의도 tagger.tags()로 토큰화한 뒤 검색하세요.

Q. 실시간 색인 성능은 괜찮나요?

바른은 ONNX 런타임 기반으로 빠르게 추론합니다. 대량 색인은 문서를 배치로 묶어 tags([...])에 여러 문장을 한 번에 넘기면 처리량을 높일 수 있습니다.

Q. 바른과 Elasticsearch는 어떻게 연동하나요?

바른은 색인 파이프라인의 전처리 단계에 둡니다. 문서 본문을 바른으로 분석해 형태소 토큰 배열을 만든 뒤 whitespacekeyword 분석기로 그대로 색인하고, 검색 질의도 같은 바른 분석기로 토큰화합니다. REST로 호출할 때는 Connect 경로(POST /bareun.LanguageService/AnalyzeSyntax)를 사용하면 됩니다.

관련 문서

도움이 되었나요?