MySQL에서 형태소 분석 및 전문검색 방법
개요
- Elasticsearch를 활용한 검색만을 사용하다가, ES검색을 사용하지 않고 DB로만 사용하고 싶다는 요구가 있어 만들어보게 되었다.
- 먼저, InnoDB에서 지원하는 FTS를 사용하여 ngram을 추가하고, 검색결과 고도화를 위해 MeCab을 이용하여 형태소 분석을 진행하였다.
1. MySQL FullText Search
- MySQL 내 MyISAM은 MySQL5.5버전 이상부터 지원하고, InnoDB는 MySQL 5.6버전부터 FTS(FullText Search)를 지원한다. CJK(중국어, 일본어, 한국어)를 지원한다.
- 기본적인 InnoDB 전문검색(FTS)는 구분자(공백, 단어분리자)를 이용하여 토큰을 생성한다. 하지만 한국어는 조사와 같은 품사가 있어, 다른 방법을 사용해야 한다.
- 인덱스 파서 방식은 여러가지가 있지만 검색 시 가장 매칭이 높게 나올 수 있는
ngram parser
방식을 사용하여 토큰화 해보았다. -
minimum_length
가 2인 경우ex) 대한민국 analyzer => 대한, 한민, 민국
-
minimum_length
가 3인 경우ex) 대한민국 analyzer => 대한민, 한민국
위와 같이 MySQL에서 ngram은 단일 길이로만 토큰이 생성된다. 최소~최대 길이 ngram 토큰을 생성하는 Multi parser index를 사용하는 방식도 존재한다고 한다.
-
사용방법
-
Table 생성 시 검색 대상 필드에 사용한 분석기와 FTS 인덱스 설정 / 테이블 수정
mysql> CREATE TABLE articles ( FTS_DOC_ID BIGINT UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY, title VARCHAR(100), FULLTEXT INDEX ngram_idx(title) WITH PARSER ngram ) Engine=InnoDB CHARACTER SET utf8mb4; Query OK, 0 rows affected (1.26 sec) mysql> # ALTER TABLE articles ADD FULLTEXT INDEX ngram_idx(title) WITH PARSER ngram; mysql> # CREATE FULLTEXT INDEX ngram_idx ON articles(title) WITH PARSER ngram;
데이터 생성…
-
토큰화된 데이터 확인 및 결과 유추
mysql> INSERT INTO articles (title) VALUES ('my sql'); Query OK, 1 row affected (0.03 sec) mysql> SET GLOBAL innodb_ft_aux_table="test/articles"; Query OK, 0 rows affected (0.00 sec) mysql> SELECT * FROM INFORMATION_SCHEMA.INNODB_FT_INDEX_CACHE;
Set Global 쿼리는 테이블 최적화 시 테이블 크기에 따라 오래 걸릴 수 있기 때문에 FullText에 대한 캐시 확인
-
검색 시 SQL
mysql> SELECT * FROM articles WHERE MATCH(title) AGAINST('sql' IN BOOLEAN MODE);
추가적으로 제외어, 조건절 등 여러 검색 연산자를 지원함.
조건절 설명 + and 조건 - not 조건 < 검색순위 하햫 > 검색순위 상향 () 검색결과 내 검색 ~ 검색순위 최저 하향 * 검색어 기준 전체검색 "” 구문검색 mysql> SELECT * FROM articles WHERE MATCH(title) AGAINST('+sql -my' IN BOOLEAN MODE);
-
문제점
(정확성)해당 Analyzer를 사용했을 때, 검색의 결과는 나오지만, 사용자 니즈에 맞는 정확한 검색결과를 돌출하지 않는다.
ex) 검색어: ten result: sentence, ten, ...
위 에시에서 숫자를 검색했을떄 뜻하지 않은 sentence가 반환된다.
사용자의 의도를 파악하여 결과를 반환하려면 의미있는 단어에 대한 필터링이 필요했다.
위 조건에 맞추려면 형태소 분석이 필요하여 플러그인을 추가하게 되었다.
-
stopWord는 불용어 용어집을 추가하고, 토큰을 확인하여 불필요한 단어 추가
-
</br>
2. MeCab, 한국어 형태소 분석
- MySQL에서 MeCab을 플러그인 형태로 지원하고 있어 사용하게 되었다.
- MeCab은 일본어 형태소 분석기 플러그인으로써, 기본적으로 한국어는 존재하지 않는다. 해당 플러그인으로 한국어 형태소 분석을 하기 위해 은전한닢의 사전을 사용한다.
- 은전한닢과 MaCab의 설치, 연결되어 있다는 가정으로 진행함
- 은전한닙, MeCab 설치 =>
-
Mysql 설정에 플러그인 등록
vi /etc/mysql/my.cnf # mecab 한국어 사전 추가 [mysqld] loose-mecab-rc-file = /path/to/mecab/etc/mecabrc innodb_ft_min_token_size = 1
- 플러그인 설치
install plugin mecab soname 'libpluginmecab.so';
- 테이블 생성 및 사용
mysql> CREATE TABLE articles_mecab (id SERIAL PRIMARY KEY, title VARCHAR(255), FULLTEXT(title) WITH PARSER mecab) CHARACTER SET utf8; Query OK, 0 rows affected (1.26 sec)
-
결과 확인
mysql> INSERT INTO articles_mecab (title) VALUES ('my sql'); Query OK, 1 row affected (0.03 sec) mysql> SET GLOBAL innodb_ft_aux_table="test/articles_mecab"; Query OK, 0 rows affected (0.00 sec) mysql> SELECT * FROM INFORMATION_SCHEMA.INNODB_FT_INDEX_CACHE;