이전글에서 활용한 MySQL의 fulltext index는 다음 2가지 종류의 paresr를 이용하여 인덱스를 구축한다.
' ' | ',' | '.'같은 특정 구분 문자로 단어가 시작되고 끝나는 위치를 결정합니다.
ex) 바다 위를 걷는 듯한 기분이 들었다.
-> "바다" | "위를" | "걷는" | "듯한" | "기분이" | "들었다"공백을 기준으로 6개의 토큰이 인덱싱 된다.
위의 parser는 구분 단어를 사용하지 않는 언어(ex. 중국어)를 사용할 때 제한된다. 이러한 제한을 해결하기 위해 MySQL은 중국어, 일본어 및 한국어(CJK)를 지원하는 ngram parser를 제공한다.
ngram parser는 일련의 텍스트를 n개의 문자로 구성된 연속된 시퀀스로 토큰화합니다.
예를 들어, ngram parser를 사용하여 n의 다른 값에 대해 "abcd"를 토큰화할 수 있습니다.
n=1: 'a', 'b', 'c', 'd'
n=2: 'ab', 'bc', 'cd'
n=3: 'abc', 'bcd'
n=4: 'abcd'
토큰 사이즈가 2일 때, 한글로 예를 들면 아래와 같다.
ex) "바다 위를 걷는 듯한 기분이 들었다."
-> "바다" | "위를" | "걷는" | "듯한" | "기분" | "분이" | "들었" | "었다"
공백을 포함한 토큰은 제외하고 8개의 토큰이 인덱싱된다.
ngram parser의 default token size는 2이다.
Token size는 아래와 같이 확인할 수 있으며, my.conf 구성 파일에서 수정할 수 있다.
mysql> SHOW GLOBAL VARIABLES LIKE "ngram_token_size";
+------------------+-------+
| Variable_name | Value |
+------------------+-------+
| ngram_token_size | 2 |
+------------------+-------+
1 row in set (0.01 sec)
n-gram에서 공백은 항상 제외 된다.
예를 들어 "ab cd" 는 "ab" , "cd" 로 구문 분석되며, "a bc" 는 "bc" 로 구문 분석이 됩니다.
일반적으로 토큰화된 단어가 stopwords 테이블에 완전히 일치하는 단어가 있다면 그 단어는 인덱스에 추가되지 않는다. 하지만, n-gram parser는 토큰화된 단어에 stopwords가 포함되어 있는지 확인하고 포함되어 있다면 토큰을 제외한다.
예를 들어 토큰 크기가 2라면, "a,b"가 포함 된 문서는 "a," 와 ",b" 로 구문 분석된다.
이 때 쉼표 (",")가 stopwords 로 정의된 경우, "a," 와 ",b" 는 모두 쉼표를 포함하므로 검색에서 제외된다.
자연어 모드 검색(natural language mode)에서는 용어들의 조합(union) 검색으로 변환된다.
불린 모드 검색(boolean mode)의 경우 구문(phrase) 검색으로 변환된다.
예를 들어 토큰 크기가 2라면 문자열 "abc"는 "ab bc"로 변환되며, "ab"을 포함하는 문서와 "abc"를 포함하는 문서 두 개가 주어졌다고 가정해 보자.
"ab bc"로 탐색을 하게 되면,
자연어 모드의 경우, "ab"을 포함하는 문서와 "abc"를 포함하는 문서 두 개가 일치한다.
하지만 불린 모드의 경우, "abc"를 포함하는 문서만 일치한다.
와일드카드 검색의 접두사가 ngram 토큰 크기보다 짧으면,
쿼리는 접두사로 시작하는 ngram 토큰을 포함하는 인덱스된 모든 행을 반환합니다.
예를 들어, ngram_size=2를 가정하면 "a*"에 대한 검색은 "a"로 시작하는 모든 행을 반환합니다.
와일드카드 검색의 접두사가 ngram 토큰 크기보다 길면,
접두사 용어가 ngram 구문으로 변환되고 와일드카드 연산자는 무시됩니다.
예를 들어, ngram_size=2를 가정하면 "abc*" 와일드카드 검색은 "ab bc"로 변환됩니다.
Phrase 검색은 ngram Phrase 검색으로 변환된다.
예를 들어, 검색어 "abc"는 "abc"와 "ab bc"를 포함하는 문서를 반환하는 "ab bc"로 변환된다.
검색어 "abc def"는 "abc def"와 "ab bc de ef"를 포함하는 문서를 반환하는 "ab bc de ef"로 변환된다. 하지만 "abcdef"가 포함된 문서는 반환되지 않는다.