pile·
DB / 데이터·티몬티몬·

ES플러그인 커스터마이징 (3)ㅎㅇㅇㅎ검색 대응하기

티몬 ES 플러그인 커스터마이징 3부로, 자동완성에 필요한 한글 자모 분해와 초성 검색을 담당하는 TokenFilter 를 만든다. "해외여해" 로 검색해도 "해외여행" 이, "ㅎㅇㅇㅎ" 로 검색해도 같은 결과가 나오게 하는 두 요구를 하나의 필터 구조로 흡수한다.

핵심 포인트
  • 현재 자모 분석 로직이 API 와 색인 배치 양쪽에 흩어져 있어, 분석 방법을 바꾸려면 두 곳을 모두 고쳐야 한다. "변화는 한 곳으로 집중시켜야 한다" 는 원칙에 어긋나는 상태다.
  • 그래서 로직을 검색엔진으로 옮길 것을 전제로, 그때 쓸 분석 필터를 미리 만든다.
  • 부분일치(해외여해 → 해외여행)는 자모 분해로, 초성일치(ㅎㅇㅇㅎ → 해외여행)는 한글의 초성 특성으로 각각 해결된다.
  • 두 요구를 동시에 만족시키려고 Parser 를 별도로 두고, TokenFilter 는 전달받은 Parser 의 `parse()` 만 호출하도록 설계했다.
  • 어떤 Parser 를 넘길지는 TokenFilterFactory 가 정하므로, 새 파서가 추가돼도 필터 클래스는 수정할 필요가 없다.
상세 정리
  • 책임 분리의 효과: 분석에 대한 책임을 Parser 구현체가 지므로 이후 바뀌는 요구사항을 맞추기 수월해진다.
  • 필터의 역할은 생성자로 받은 Parser 가 만든 결과를 버퍼에 담아 반환하는 것뿐이다.
  • 분기 방식: TokenFilterFactory 가 settings 의 파라미터 값을 보고 자모 분해 분석기와 초성 분석기 중 하나를 만들어 넘긴다.
  • 유니코드 상수: 한글 소리마디의 시작 코드포인트(가), 한글 총 글자 수, 중성 총 글자 수, 종성 총 글자 수, 그리고 중성 수×종성 수로 계산되는 기본값을 상수로 선언한다.
  • 호환형 자모 코드포인트도 초성·중성·종성별 배열로 정의하며, 채움 문자를 포함해 인덱스를 맞춘다.
  • 분해 원리: 유니코드는 문자마다 코드포인트를 가지며 언어별 출현 위치가 정해져 있어, 그 위치 정보를 기반으로 초성·중성·종성을 계산해 분리한다.
  • 처리 분기: 현재 문자가 완성형 한글이면 자모를 분해하고, 분해가 불가능하면 Letter 인 경우에만 결과 셋에 추가한다.
  • 확장 지점: 추상 클래스가 분해한 초성·중성·종성을 구현체에 그대로 넘겨주므로, 구현자가 원하는 방식으로 조합할 수 있다.
  • `TmonJamoParser` 는 "해외여해" 로 검색해도 "해외여행" 이 걸리도록 초성·중성·종성을 결합해 토큰을 만든다.
  • `TmonChosungParser` 는 넘겨받은 셋 중 초성만 토큰으로 반환해 초성 검색을 담당한다.
  • 마지막으로 TokenFilterFactory 가 생성자에서 받은 파라미터로 어떤 Parser 를 쓸지 결정한다.
  • 앞선 1·2부에서 플러그인 개발 절차를 다뤘으므로 이 글은 절차를 생략하고 분석기 설계에만 집중한다.
왜 읽나한글 자동완성을 검색엔진 쪽에서 처리하려는 개발자에게 자모 분해·초성 추출 필터의 구조와 유니코드 계산 근거를 준다.
티몬
티몬 블로그
원문은 여기서 이어서 읽을 수 있어요
원문 읽기
읽음 (0)

이 글과 비슷한

  1. DB / 데이터·여기어때 (GC컴퍼니)여기어때 (GC컴퍼니)·

    분석가가 직접 만든 마케팅 자동화 시스템 — 오디언스 빌더 제작기

    여기어때 데이터 분석팀(UB팀)이 개발 경험 없이 AI 에이전트 바이브 코딩으로 마케팅 자동화 시스템 '오디언스 빌더'를 구축한 과정이다. SQL 없이 UI에서 타겟 조건을 설정하면 BigQuery에서 수천만 행 대상자를 추출해 Kafka·S3를 통해 마케팅 도구로 전달하는 파이프라인을 직접 만들어, 캠페인 준비 시간을 2~3일에서 10분으로 단축했다.

    요약 이어보기
    #data-pipeline#kafka#postgres+2
  2. DB / 데이터·vercel-blogVercel Blog·

    모든 Vercel 빌드를 지탱하는 데이터베이스 마이그레이션 이야기

    Vercel이 빌드 웜 풀(warm pool) 상태 데이터를 Redis에서 DynamoDB로 마이그레이션한 과정을 다룬다. 빌드 풀의 청구 매핑 데이터가 Redis 장애 시 복구 불가능하다는 구조적 위험이 이주를 결정한 핵심 이유였고, 24/7 프로덕션 트래픽 속에서 다운타임 없이 5단계 점진적 전환을 완료했다.

    요약 이어보기
    #database-migration#zero-downtime#redis+2
  3. DB / 데이터·channel-talk채널톡·

    DynamoDB 핫 파티션을 해결하는 3가지 방법 (3): 조회를 인덱스 테이블로 옮기기

    채널톡이 DynamoDB 핫 파티션을 해결하려 GSI를 별도 인덱스 테이블로 떼어낸 연재의 마지막 편으로, 조회 경로를 GSI에서 인덱스 테이블로 옮긴 과정을 다룬다. 2편에서 쓰기 파이프라인이 완성돼 WriteThrottleEvents가 월 110만 회에서 0회가 됐지만, 조회 코드가 여전히 GSI를 읽고 있어 GSI를 지울 수 없었다. GSI가 읽기에서 대신해주던 키 해석·정확 일치·삭제 필터·페이지 채우기를 사내 공통 라이브러리의 조회 규칙으로 흡수해, 호출부는 GSI든 인덱스 테이블이든 같은 코드를 쓰게 만들었다.

    요약 이어보기
    #migration#dynamodb#hot-partition+5