Analysis 정의 : 검색에 사용할 역색인을 생성/추가하기 위해서 text를 토큰화하는 작업.
* 아날라이저는 index time 또는 search time 에 built-in 된거나 혹은, 인덱스 단위로 custom analyzer 를 적용할 수 있다.
- index time analysis 예시
PUT my_index { "mappings": { "my_type": { "properties": { "title": { "type": "text", "analyzer": "standard" } } } } }
-- search text
"The QUICK brown foxes jumped over the lazy dog!"
-- inverted index result
[ quick, brown, fox, jump, over, lazi, dog ]
* 각각의 text field 는 자기만의 아날라이저 세팅이 가능하다
* index time 에 analyzer 가 세팅되지 않았다면 defalut로, statndard_analyzer 가 사용된다.
[Analyzers] -> 유니코드 텍스트 세그먼트를 기반으로한 토크나이저 수행. 유니코드라서 대부분 언어에서 잘 동작하는듯
* analyzer = tokenizer + token filter 이다.
관련 자료는 더 있지만, 간략하게 "띄어쓰기" 기반으로 토큰화 된다고 이해해도 무방할듯..?
아래는 이해를 돕기 위한 아날라이저 동작 방식 샘플 사진.
원본 텍스트로부터 여러 토큰들을 생성하고(tokenizer), 생성된 토큰들에 필터들을 적용(token filter) 하는 방식
[Configuration]
standard analyzer 는 다음의 파라미터들을 갖는다.
| The maximum token length. If a token is seen that exceeds this length then it is split at |
| A pre-defined stop words list like |
| The path to a file containing stop words. |
* 보통 인덱싱 타임과 쿼리 타임에 사용하는 아날라이저는 동일해야하지만, 각 시점에서 다른 아날라이저를 사용하도록 설정할 수 있다.
-> 고려해봄직은 한게, 인덱싱할때는 token 조차 n-gram 단위로 쪼개서 저장하고, search 때 부분 문자로 찾을 때 사용할 수 있을 것 같다.
[종류]
- Standard Analyzer
text 를 Unicode Text Segmentation Algo 에 기반하여 단어(term)로 나눈다. 대부분의 구두법과 소문자 terms, 그리고 stop words 제거를 지원한다.
- Simple Analyzer
문자가 아닌 캐릭터셋을 구분자로 인식하여 텍스트를 모두 소문자로 토크나이저한다.
- Whitespace Analyzer
text를 공백을 구분자로 하여 토크나이저한다. 소문자화하지 않는다.
- Stop Analyzer
Simple Analyzer 와 비슷하게 동작하지만, stop words 를 제외한다.
- Keyword Analyzer
text 를 토크나이저한 결과가 정확히 text 와 같다. (단일 텀)
- Pattern Analyzer
text 를 정규표현식을 사용해서 토크나이저한다. 소문자화, stop word 를 지원.
- Language Analyzer
es는 여러 언어들을 지원하고, 각각의 언어에 특화된 아날라이저를 지원한다.
-> 유니코드 텍스트 기반이라 따로 적용안해도 문제 없는듯 하지만 정확도를 위한건가?
- Fingerprint Analyzer
fingerprint 알고리즘을 사용해서 클러스터에서 중복을 없애기 위해 사용하는 것 같다...
[Tokenizers]
위에 아날라이저 종류에서 언급한 기능들이 주로 토크나이저의 기능이라서, 기본 토크나이저 종류 또한 위의 리스트와 같다. 다만 "부분 검색" 을 지원할 수 있는 N-Gram 토크라이저 두 가지를 정리한다.
- N-Gram Tokenizer
text 를 특정 Charcter Set 을 기준으로 나눌 수 있다. (e.g 공백, 마침표) . 연속된 문자들의 sliding window 를 결과로 내보낸다.
eg) quick => [qu, ui, ic, ck]
- Edge N-Gram Tokenizer
N-Gram Tokenizer 와 비슷하지만 sliding window 결과가 아니라, 문자 시작으로부터 offset 만큼의 단어 리스트를 내보낸다. (anchored to the start of the word)
eg) quick => [q, qu, qui, quic, quick]
N-Gram 은 부분 검색에, Edge N-Gram 은 자동완성과 같은 기능에 사용하면 될 듯 하다.
마지막으로, 현재 구현하려는 부분 검색에 필요할 법한 Custom Analyzer 예시를 생성해본다.
조건
1. 부분 검색이기 때문에 text 를 토크나이저 한 후에 N-Gram 으로 다시 한번 필터링한다.
2. a
, b
, ï
or 京
같은 문자들, 3 or 7 같은 숫자들을 토크나이저 대상으로 삼고, 나머지(공백, 특수문자 등)는 구분자로 간주한다.
3. ngram 단위를 1로 잡으면 토큰이 너무 많아지고, 크게 잡으면 히트율이 떨어지므로 min_gram 값은 3으로 잡았다.
PUT MY_INDEX
{
"settings": {
"analysis": {
"analyzer": {
"ngram_analyzer": {
"tokenizer": "ngram_tokenizer"
}
},
"tokenizer": {
"ngram_tokenizer": {
"type": "ngram",
"min_gram": 3,
"max_gram": 3,
"token_chars": [
"letter",
"digit"
]
}
}
}
}
}
result
{
"acknowledged": true,
"shards_acknowledged": true
}
POST MY_INDEX/_analyze
{
"analyzer": "ngram_analyzer",
"text": "2 Quick Foxes."
}
result
{
"tokens": [
{
"token": "Qui",
"start_offset": 2,
"end_offset": 5,
"type": "word",
"position": 0
},
{
"token": "uic",
"start_offset": 3,
"end_offset": 6,
"type": "word",
"position": 1
},
{
"token": "ick",
"start_offset": 4,
"end_offset": 7,
"type": "word",
"position": 2
},
{
"token": "Fox",
"start_offset": 8,
"end_offset": 11,
"type": "word",
"position": 3
},
{
"token": "oxe",
"start_offset": 9,
"end_offset": 12,
"type": "word",
"position": 4
},
{
"token": "xes",
"start_offset": 10,
"end_offset": 13,
"type": "word",
"position": 5
}
]
}
* n 을 3으로 잡았기 때문에 "2" 는 무시되었다.
* 인덱스의 아날라이저 세팅은 운영중에도 바꿀 수 있긴 하지만 글쎄....
'아카이브 > ElasticSearch' 카테고리의 다른 글
[5.4] 데이터 자료형 (0) | 2017.06.28 |
---|---|
블로깅전 url 기록 (0) | 2017.06.26 |