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

ES플러그인 커스터마이징 (1)어떠한 검색어도 의미있는 추천을

티몬이 커머스 검색 요구사항을 맞추려고 직접 만든 Elasticsearch 플러그인을 소개하는 1부다. 플러그인 타입 세 가지를 정리한 뒤, 관리자와 검색엔진 양쪽에서 중복으로 하던 검색어 분석을 ES 쪽으로 몰아넣은 커스텀 TokenFilter 개발 과정을 다룬다.

핵심 포인트
  • Elasticsearch 는 Lucene 기반이라 그대로도 웬만한 검색은 되지만, 커머스는 요구사항이 다양해 엔진 커스터마이징이 필연적이라는 전제에서 출발한다.
  • 플러그인 타입은 세 가지다. Java 플러그인은 jar 만 담고 모든 노드에 설치 후 재구동이 필요하다.
  • Site 플러그인은 정적 웹 콘텐츠를 담아 한 노드에만 설치하면 다른 노드로 자동 전파되고 재구동 없이 `_plugin/<이름>` URL 로 바로 접근된다. head 가 대표적이다.
  • Hybrid 플러그인은 둘이 섞인 형태로, 재구동이 필요하면서 URL 접근도 가능하다. 이 글은 분석기 개발이므로 Java 플러그인만 쓴다.
  • 기존 구조의 문제는 검색어 분석을 관리자 페이지와 검색엔진 양쪽에서 해야 했다는 점이다. 요구사항이 바뀌면 두 곳을 모두 고쳐야 했고 관리자 페이지가 분석기 역할까지 하는 주객전도가 일어났다.
상세 정리
  • 버전 전제를 먼저 밝힌다. ES 5.x 이후로 플러그인 종류가 크게 달라져 이 글은 사내에서 쓰는 버전 기준으로 설명한다.
  • 문제의 뿌리: 관리용 저장소는 RDB, 검색용은 캐시를 쓰다 보니 검색어를 분석할 방법이 없어 관리자가 입력한 검색어를 가공해 저장하는 방식이 됐다.
  • 그 부작용으로 공백 등 다른 문자가 섞인 검색어의 통계 집계가 제대로 되지 않았다.
  • 개선 방향: ES 를 도입하면서 검색어 분석에 대한 모든 책임을 ES 로 위임하고, 그 역할을 하는 TokenFilter 플러그인을 직접 만들었다.
  • 개발 절차는 다섯 단계다. Gradle 프로젝트에 의존성 추가 → `TokenFilter` 상속 구현 → `TokenFilterFactory` 상속 구현 → 테스트 → jar 를 `plugin-descriptor.properties` 와 함께 묶어 배포.
  • 의존성 주의점: elasticsearch 라이브러리 버전을 실제 운영 중인 ES 버전과 반드시 일치시켜야 한다.
  • TokenFilter 의 역할: Tokenizer 가 분해한 각 토큰마다 추가 분석이 필요할 때 쓴다. `incrementToken()` 을 구현해 분석할 게 남으면 true, 끝났으면 false 를 반환한다.
  • 구현 의도: 제작형 컨텐츠는 유의미한 검색어만 대상이 되어야 하므로, 의미 있는 문자와 숫자만 추출하는 메서드를 통과시킨 토큰을 term attribute 에 담는다.
  • 동작 예시로 사용자가 특수문자 섞인 검색어를 입력해도 관리자가 등록한 키워드를 포함하면 노출되어야 한다는 요구를 든다.
  • TokenFilterFactory 는 이름 그대로 실제 TokenFilter 생성을 담당한다.
  • 배경 서비스 설명: 제작형 컨텐츠는 특정 검색어가 들어왔을 때 MD 가 엄선한 딜을 추천해 주는 기능이다.
왜 읽나Elasticsearch 기본 분석기로는 안 되는 요구를 만난 검색 담당 개발자에게 커스텀 TokenFilter 를 만드는 최소 절차와 함정을 준다.
티몬
티몬 블로그
원문은 여기서 이어서 읽을 수 있어요
원문 읽기
읽음 (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