공부내용공유

MongoDB 전문 검색 (Full Text Search) 본문

Server/MongoDB

MongoDB 전문 검색 (Full Text Search)

forfun 2024. 1. 28. 19:57

서론


프로젝트를 하면서 검색 기능을 구현해야 했다. 기능 구현을 위해 알아봤던 내용을 간단하게 정리하였다.

 

본문


전문 검색 인덱스(Full Text Search Index)

Full-Text-search-index(전문 검색 인덱스)란 많은 형태의 데이터가 있을 때 효율적으로 데이터를 찾는 방법중 하나로 텍스트로 구성된 데이터의 내용을 기반으로 생성한 인덱스이다.

 

메일, 메세지 내용을 기반으로 검색을 할 때 효율적으로 검색하기 위해 필요하다.

 

MongoDB 전문 검색 인덱 알고리즘

  • 불용어(stop word) 처리
    • 가치 없는 단어를 필터링
    • 주로 대명사, 관사, 전치사, 주요 동사
  • 형태소 분석
    • 검색어로 선정된 단어의 어근을 찾는 작업

 

처리과정

불용어 처리

there are not droids you are looking for 을 입력하면 나머지는 전부 불용어 처리에서 걸러지고 droids, looking만 남을 것이다.

 

형태소 분석

s, es,ed, ing등을 제거해서 단어의 원형을 찾아서 작업을 마친 단어들을 인덱스에 저장한다. 전문 검색 인덱스이긴 하지만 멀티 키 인덱스와 동일한 자료구조로 저장한다.

 

이후 사용자가 단어를 검색하면 멀티 키 인덱스를 통해 검색을 하면된다. 이때 사용자가 검색할 때도 불용어가 포함되고 원형이 아닐 수 있기 때문에 입력과 동일한 프로세스를 거치고 인덱스 검색을 한다.

 

N-Gram 알고리즘

그러나 MongoDB에서 사용하는 stop-word 방식은 언어마다 다르게 분석해야 하는 한계가 있고 이를 보완하기 위해 N-Gram 알고리즘이 나왔다.

 

N-Gram이란 모든 언어를 무조건으로 몇 글자씩 잘라서 인덱싱하는 방법이다.

구분자보다 인덱싱 알고리즘이 복잡하고 인덱스 사이즈도 크지만 Elastic Search, Sphinx도 N-Gram 알고리즘을 사용한다.

 

N은 인덱싱할 키워드의 최소 글자 수를 의미하는데 보통 2-Gram 방식이 많이 이용된다.

 

형태소 분석 vs N-Gram

형태소 분석 N-Gram

언어 의존도 국가별로 언어가 달라 형태소분석 알고리즘도 달라져야 한다. 문자열을 일정한 규칙에 따라 문장을 분할해서 인덱싱 하므로 언어의 특성과 무관하다.
인덱스 크기 가치가 없는 단어는 모두 필터링하고 중복된 어근들은 제외하기에 전문 인덱스 크기가 작다. 대상 문자열을 모두 잘라서 인덱싱하기 때문에 필요 없는 부분까지 인덱싱되고 크기가 커진다.
성능 인덱스 크기가 적다는 것은 전문 인덱스에 추가해야 하는 것이 작다는 것이다. 이는 삭제, 저장등이 더 빠름을 의미한다. 많은 인덱스 키를 관리하므로 상대적으로 느리다.
검색 품질 형태소 분석 알고리즘에 따라 품질 차이가 심하다 언어별 분석이 필요없고, 부분 일치가 가능하므로 적은 투자로 평균 이상의 품질을 얻을 수 있다.

 

차이 예시

blueberry를 인덱스와 시켰을 때

  • 형태소분석 : blueberry
  • N-Gram : blue+berry or blueb+erry

이런식으로 인덱스가 생성된다.

사용자가 blueverry라고 오타를 친 경우 stop-word는 완전 다른 단어로 취급한다.

N-Gram 기반 검색엔진은 blue, erry로 쪼개져 있으면 연관 단어로 갖고올 수 있다.

 

고민할 점

동양권 언어는 서구권 언어와 다르게 형태소 분석이 어렵다. 또 MongoDB에서는 한국어 지원을 안하고 있기 때문에 일반 형태소 분석으로 한국어 전문 검색은 정확도가 굉장히 떨어진다.

 

https://www.mongodb.com/docs/manual/reference/text-search-languages/#text-search-languages

 

이에대한 대안으로는 3가지 정도가 있는거 같다.

  1. Elastic Serach
    1. 검색엔진으로는 제일 많이 사용되고있는 오픈소스이고 그중 Nori가 한글 형태소 분석기로 제일 많이 사용된다.
  2. Mongo Atlas
    1. 몽고DB의 cloud 서비스인 atlas에서 elastic search의 한국어 형태소 분석 알고리즘인 nori를 이용하여 검색을 지원해준다.
  3. Percona MongoDB (N-Gram)
    1. Percona MongoDB 3.4버전 이상부터 N-Gram FTS를 내장화 시켜서 N-Gram 방식으로 검색이 가능해졌다.

 

Elastic Serach

현재 프로젝트에 적용하기에는 무겁고 공부할 시간도 충분치 않아 부담스러운 감이있다.

 

Mongo Atlas

편하게 MongoDB를 이용하면서 elastic search의 nori를 사용할 수 있으나 CloudDB라는 점이 걸린다. 데이터에 관하여 걸리는 규정이 없고 시험삼아 해본다면 괜찮을 수도 있을것 같다.

 

Percona MongoDB

N-Gram을 내장하고 있다. K사에서도 N-Gram을 커스터마이징하여 사용하다가 내장화된 후로 Percona를 사용했다고 한다.

In-memory 스토리지 엔진, 암호화 기능등 기존 community 버전에서는 유료인 기능도 사용이 가능하다고 한다.

LocalDB로 사용하면서 적당한 성능의 검색기능을 구현하는데 적합한것 같다.

 

결론


이렇게 mongoDB를 사용한 전문 검색 기능을 구현하는 방법들을 알아보았다.

 

하지만 진행한 프로젝트에서는 일단은 전문검색 인덱스를 사용하지 않게되었다...

 

그 이유는 like 검색 쿼리를 사용했을 때 몇십만 건까지는 성능차이가 크게 없었고 검색기능은 사용자 데이터 검색정도라 전문 검색 인덱스는 오버 엔지니어링이라 판단하였기 때문이다. 

 

언젠가 필요한 상황이 생기게 되면 더 자세히 알아보고 다양한 방법들을 직접 적용해 보고 실험할 예정이다.