본문 바로가기

아카이브/ElasticSearch

[5.4] analyzer

반응형

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 는 다음의 파라미터들을 갖는다.


max_token_length

The maximum token length. If a token is seen that exceeds this length then it is split at max_token_length intervals. Defaults to 255.

stopwords

A pre-defined stop words list like _english_ or an array containing a list of stop words. Defaults to \_none_.

stopwords_path

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. abï 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