리버스 안 나오는 펜슬 검색서버 만들기
리버스 보려고 검색한게 아니였는데
펜슬이 출시된 후 SNS에서 많이 이야기가 나왔던 문제 중 하나가 '검색결과에 리버스가 나온다'였습니다.
리버스란 간단히 설명해서 AB 커플링을 검색했는데 BA가 나오는 문제를 말합니다. 이는 캐릭터 해석의 문제이므로 동인판에선 매우매우매우매우 중요합니다.
얼핏 간단히 해결할 수 있을 줄 알았던 이 문제를 해결하는데 생각보다 많은 시간이 걸렸는데요, 해결하는 과정에서 처음 겪어보는 이슈들을 많이 겪어보았기에 이 포스트를 통해 간단히 상황과 시도들을 정리하게 되었습니다.
서버가 터지기 전에 검색하기
24년 1월 8일 기준으로, 펜슬에는 약 15,000개의 포스트가 발행되었습니다. 검색을 할 때마다 이 만여개의 포스트들을 하나하나 체크해본다면 아마 서버를 10배 쯤은 늘려야 할지도 모릅니다.
그렇기 때문에, ElasticSearch 같은 검색 서버들은 모든 검색 대상 문서들을 하나하나 대조해보는 대신, 역 인덱스(Inverted Index)라는 방법을 사용합니다.
역 인덱스?
역 인덱스는 일반적인 문서 구조랑 반대로, 문서 속의 키워드로 문서를 찾도록 구성된 인덱스입니다. 역 인덱스를 통해 특정 키워드가 들어간 문서를 쉽게 찾을 수 있습니다.
(이미지 출처: https://spotintelligence.com/2023/10/30/inverted-indexing)
포스트가 발행될 때 검색될 내용들을 키워드로 분리하고, 역 인덱스를 미리 만들어두면 나중에 검색할 때 모든 문서를 일일히 찾아볼 필요 없이 쉽게 찾을 수 있을 것입니다.
그럼 그 키워드란 건 어떻게 분리해야 할까요?
토크나이저와 애널라이저
토크나이저란 문서의 텍스트들을 키워드(토큰)으로 분리하는 도구이며, 애널라이저는 분리된 토큰을 검색에 사용하기 적절하게 가공하는 도구입니다.
ElasticSearch의 기본 토크나이저는 띄어쓰기를 기준으로 토큰을 분리하는데요, 단어들이 띄어쓰기로 구분되는 영어 텍스트에 사용하기는 적절하지만 한국어에 사용하면 '펜슬이', '펜슬은', '펜슬로' 등등이 모두 다른 토큰으로 분류되기 때문에 적절하지 못합니다.
한국어의 희망 nori
nori는 Elastic사에서 제작한 한국어 형태소 분석기입니다. nori 토크나이저를 사용하면 띄어쓰기로 구분되지 않는 한국어 텍스트를 형태소 단위로 구분해 토큰으로 만들 수 있고, nori 애널라이저를 통해 검색에 불필요한 조사, 접두사 등의 토큰을 제거해 검색에 필요한 핵심 토큰만 남길 수 있습니다.
펜슬의 초기 검색 역시 nori를 사용해 제작되었습니다.
그런데 우리 동인창작 서비스인데요??
일반적인 한국어 서비스라면 nori를 사용하는 것으로 문제가 해결되었겠지만, 펜슬은 동인 창작 서비스입니다. 검색 측면에서 일반 서비스와의 가장 큰 차이라면, 검색의 핵심 키워드가 커플링명이라는 점이죠.
커플링명에 형태소 분석을 적용하면 결과가 이상하게 나올 확률이 큽니다. 단적인 예시로 SNS에서 펜슬 검색결과에 리버스가 뜬다고 논란이 되었던 모 커플링도 커플링명을 nori가 접두사 + 명사 식으로 분석하고 '검색에 불필요'한 접두사를 제거해 발생한 문제였습니다.
토큰 추출 과정 자체가 잘못되었기에, match_phrase 쿼리로 토큰의 순서까지 체크했음에도 일부 커플링의 리버스가 검색결과에 나타나는 문제가 지속되었습니다.
씨피명의 희망 ngram
ngram 토크나이저는 텍스트를 몇 글자 단위로 분리하는 토크나이저입니다. 예시를 들어 "가나다라마"라는 문자열을 2글자 ngram으로 분리하면 "가나", "나다", "다라", "라마"로 분리됩니다.
ngram은 다른 토크나이저를 사용하는 것에 비해 토큰의 수가 크게 늘어나 검색 서버 비용이 증가할 수 있으나, 동인 창작 서비스인 펜슬에서 리버스 문제를 해결하는 것은 그만큼의 비용 증가를 감수할 가치가 있기 때문에 ngram을 선택했습니다.
일반적인 한국어 커플링명에서는 한 캐릭터의 이름이 3글자를 넘지 않는 경우가 대부분이기 때문에, 펜슬에서는 검색의 정확도를 위해 2글자 ngram과 3글자 ngram을 같이 인덱싱하고 있습니다.
결론과 TMI
이러한 과정을 통해 펜슬 검색의 리버스 문제가 아마도 해결되었습니다.
사실 대부분의 한국어 서비스는 nori만으로 문제가 해결되기 때문에 인터넷의 힘을 빌리지 못해서(구글이나 ChatGPT에 'ElasticSearch 리버스 안 나오게 하는 방법'같은 걸 검색해도 당연히 원하는 건 나오지 않았어요) 생각보다 삽질이 길어졌던 것 같습니다.
저도 메이저리버스를 먹던 시절이 길었던만큼 그동안 펜슬 유저분들이 겪으셨던 불편이 크다는 점 깊게 공감하고 있습니다. 이 자리를 빌어 사과드립니다.
그리고 이 문제의 중요성에 대해 공감해주시고 해결하는데 충분한 시간을 쓸 수 있도록 해주신 펜슬 팀원분들께 감사드립니다.
즐거운 덕질 되세요.
리버스도 안 나오는 희대의 마이너지만 오케파 x 아야시로는 진짜 진짜인데...
댓글 0
추천 포스트