본문 바로가기

카테고리 없음

검색 기능 구현을 위해 mysql full text search 이용하기

검색 기능 구현을 위해 mysql full text search 를 이용하는 과정에서

내가 왜 ngram parser 를 선택했는 지 그 근거를 정리하고자 한다.

 

 

1. parser 종류

mysql full text search 에서는 대표적으로 built-in mysql parser ngram parser 를 제공한다.

https://dev.mysql.com/doc/refman/8.4/en/fulltext-search-ngram.html

공식 문서에는 다음과 같이 말하고 있다.

- mysql 에서 기본적으로 제공하는 built-in parser 는 공백을 통해 단어의 시작과 끝을 결정함

ex) "hello world" -> hello 와 world 를 각각 단어로 인지 

- 그러나 한국어는 공백으로 단어의 시작과 끝을 판단할 수 없어서 built-in parser 를 이용하는게 의미가 없음

- 이를 해결하기 위해 ngram parser 를 제공할테니 한국어/중국어/일본어를 검색하는 경우에는 이 parser 이용하길 추천

 

 

2. parser 별 인덱싱 결과 비교해보기

위에서 언급한대로 한국어는 공백으로 단어를 구분할 수 없다 는 말이 사실 잘 이해가지 않아서 

built-in parser 와 ngram parser 별로 각각 어떻게 인덱싱되는 지 테스트 해봄.

built-in parser 인덱싱 결과

1. 영어

I love programming ➡️  I, love, programming

실제 인덱싱된 결과

( "I" 가 인덱싱 안 된 이유는 innodb_ft_min_token_size = 3 으로 설정되어 있기 때문 )

 

 

2. 한국어

나는 프로그래밍을 좋아합니다 ➡️ 나는, 프로그래밍을, 좋아합니다

실제 인덱싱된 결과

 

이렇게 한국어는 조사가 포함된 채로 인덱싱 되어서 검색 품질이 떨어짐

사용자가 "프로그래밍" 이라고 검색어를 입력해도 검색 결과가 나오지 않는다는 뜻임

( "나는" -> 인덱싱 안 된 이유는 innodb_ft_min_token_size = 3 으로 설정되어 있기 때문 )

 

ngram  parser 인덱싱 결과

1. 영어

I love programming ➡️ I, lo, ov, ve, pr, ro, og, gr, ra, am, mm, mi, in, ng

실제 인덱싱된 결과

( 빨간색 표시 인덱싱 안 된 이유는 stopword 에 포함되는 단어이기 때문 )

 

 

2. 한국어

나는 프로그래밍을 좋아합니다 ➡️ 나는, 프로, 로그, 그래, 래밍, 밍을, 좋아, 아합, 합니, 니다

실제 인덱싱된 결과

 

 

 

 

 

사용자는 "프로그" 까지만 쳐도 "나는 프로그래밍을 좋아합니다" 가 검색 결과에 나오길 기대할 것이다.

그런데 built-in parser 이용하면 "프로그래밍을" 이라고 정확히 입력해야만 검색 결과에 나온다. 

이유는 위 built-in parser 인덱싱 캡쳐처럼 "프로그래밍을" 이 통으로 인덱싱되기 때문이다.

그래서 한국어는 ngram parser 를 이용하는게 적합하다.

 

 

3. parser 별 stopword 를 어떻게 처리하는 지 비교

stopword = 인덱싱 안 되도록 제외되는 단어

db 레벨에서 미리 지정해 놓을 수 있음

기본적으로는 아래 캡쳐와 같이 a, about, an, are 이런 단어들이 stopword 로 지정돼있음

 

 

 

"awesome" 단어로 테스트 해봤습니다.

INSERT INTO test (content)
VALUES
('awesome');

 

 

built-in parser 인덱싱 결과

 

awesome ➡️ awesome

 built-in parser 는 인덱싱 하려는 토큰이 정확히 stopword 와 같을 때만 인덱싱에서 제외됨

awesome 은 문제 없이 인덱싱 됐음을 볼 수 있음

 

 

 

 

ngram parser 인덱싱 결과

 

awesome ➡️ aw, we, es, so, om, me

https://dev.mysql.com/doc/refman/8.4/en/fulltext-search-ngram.html

ngram parser 는 stopword 가 포함되어 있기만 해도 인덱싱에서 제외됨

그렇기 때문에 aw 가 인덱싱되지 않은거임

 

 

 

 

4. 남은 고민 거리 - DB 리전 별로 특정 컬럼에 대한 parser 를 다르게 세팅해야할까?

 

공식 문서 요약하자면 아래와 같다.

- 영어: built-in parser 추천

- 한국어: ngram parser 추천

 

그런데.. 한국인 입장에서 검색창에 영어를 입력할 때 awe 까지만 입력해도 awesome 이 결과에 바로 나오길 기대한다.

그래서 사실 한국인 입장에서 영어의 경우도 ngram parser 를 이용하는게 더 익숙한 방식이다.

 

하지만 영어권 국가의 외국인 입장에서는 아닐 수도-

mysql 문서에서 영어에 대해 built-in parser 사용을 권장하는 데는 분명한 이유가 있을 것이다

이는 외국인들이 단어 단위 검색에 더 익숙하다는 증거가 될 수 있겠다.