2.X/1. Getting Started

1-10-05. Custom Analyzers

drscg 2017. 9. 30. 17:21

While Elasticsearch comes with a number of analyzers available out of the box, the real power comes from the ability to create your own custom analyzers by combining character filters, tokenizers, and token filters in a configuration that suits your particular data.

Elasticsearch가 수많은 내장 analyzer를 제공하지만, 진정한 힘은 자신의 특별한 데이터에 적합한 설정에서, character filters, tokenizers 그리고 token filters를 조합하여, 자신만의 사용자 정의 analyzer(custom analyzer)를 생성할 수 능력에 있다.

In Analysis and Analyzers, we said that an analyzer is a wrapper that combines three functions into a single package, which are executed in sequence:

Analysis and Analyzers에서, analyzer 는 세 가지 기능을 하나의 패키지로 조합하여 감싼 것이라 언급한 바 있다. 이것은 아래의 순서로 실행된다.

Character filters

Character filters are used to "tidy up" a string before it is tokenized. For instance, if our text is in HTML format, it will contain HTML tags like <p> or <div> that we don’t want to be indexed. We can use the html_strip character filter to remove all HTML tags and to convert HTML entities like &Aacute; into the corresponding Unicode character Á.

character filters는 문자열을 분리하기 전에, "정리" 하는데 사용된다. 예를 들면, 텍스트가 HTML이라면, 그것은 색인할 필요가 없는, <p> 또는 <div> 같은 HTML tags를 포함하고 있다. 모든 HTML tag를 제거하고, &Aacute; 같은 HTML 항목을 대응하는 Unicode character Á 로 바꾸기 위해, html_stripcharacter filter를 사용할 수 있다.

An analyzer may have zero or more character filters.

analyzer는 0개 이상의 character filter를 가지고 있다.

Tokenizers

An analyzer must have a single tokenizer. The tokenizer breaks up the string into individual terms or tokens. The standard tokenizer, which is used in the standard analyzer, breaks up a string into individual terms on word boundaries, and removes most punctuation, but other tokenizers exist that have different behavior.

analyzer는 단일 tokenizer를 반드시 가진다. tokenizer는 문자열을 개별 단어나 token으로 분리한다. standard analyzer에 사용되는, standard tokenizer 문자열을 단어 경계를 기준으로 개별 단어로 분리하고, 대부분의 문장 부호를 제거한다. 그러나, 다른 동작을 하는 다른 tokenizer도 있다.

For instance, the keyword tokenizer outputs exactly the same string as it received, without any tokenization. The whitespace tokenizer splits text on whitespace only. The pattern tokenizercan be used to split text on a matching regular expression.

예를 들어 keyword tokenizer는 분리하지 않고, 받은 문자열과 정확히 똑같은 문자열을 출력한다.whitespace tokenizer는 오직 공백을 기준으로, 문자열을 분리한다. pattern tokenizer는 정규식에 일치하는, 문자열을 기준으로 분리하는데 사용될 수 있다.

Token filters

After tokenization, the resulting token stream is passed through any specified token filters, in the order in which they are specified.

분리한 후에, 분리된 token들(token stream)은 지정된 순서에 따라, 지정된 token filter를 거치게 된다.

Token filters may change, add, or remove tokens. We have already mentioned the lowercaseand stop token filters, but there are many more available in Elasticsearch. Stemming token filters "stem" words to their root form. The ascii_folding filter removes diacritics, converting a term like "très" into "tres". The ngram and edge_ngram token filters can produce tokens suitable for partial matching or autocomplete.

token filter는 token을 변경하거나 추가하거나 제거한다. 이미 lowercase 와 stop token filters를 언급했지만, Elasticsearch에는 이용할 수 있는 것들이, 훨씬 더 많이 있다. Stemming token filters는 단어를 원형으로 "형태소 분석(stem)" 한다. ascii_folding filter는 "très" 라는 단어를 "tres" 로 변경하는 것처럼, 발음 구별 부호를 제거한다. ngram 과 edge_ngram token filters는 부분 일치나 자동완성에 적합한 token을 생성할 수 있다.

In Search in Depth, we discuss examples of where and how to use these tokenizers and filters. But first, we need to explain how to create a custom analyzer.

Search in Depth에서, 이들 tokenizer와 filter를 언제 어떻게 사용하는가에 대한, 예를 들어 보겠다. 그러나 먼저, 사용자 정의 analyzer를 생성하는 방법을 설명해야 한다.

Creating a Custom Analyzeredit

In the same way as we configured the es_std analyzer previously, we can configure character filters, tokenizers, and token filters in their respective sections under analysis:

위에서 es_std 를 구성한 것과 동일한 방식으로, character filter, tokenizer, token filter를 analysis 아래의, 각각의 영역에 설정할 수 있다.

PUT /my_index
{
    "settings": {
        "analysis": {
            "char_filter": { ... custom character filters ... },
            "tokenizer":   { ...    custom tokenizers     ... },
            "filter":      { ...   custom token filters   ... },
            "analyzer":    { ...    custom analyzers      ... }
        }
    }
}

As an example, let’s set up a custom analyzer that will do the following:

예를 들어 다음과 같이, 사용자 정의 analyzer를 설정해 보자.

  1. Strip out HTML by using the html_strip character filter.

    html_strip character filter를 이용해, HTML을 제거한다.

  2. Replace & characters with " and ", using a custom mapping character filter:

    사용자 정의 mapping character filter를 사용해, & 문자를 " and " 로 대체한다.

    "char_filter": {
        "&_to_and": {
            "type":       "mapping",
            "mappings": [ "&=> and "]
        }
    }
  3. Tokenize words, using the standard tokenizer.

    standard tokenizer를 사용해, 단어를 분리한다.

  4. Lowercase terms, using the lowercase token filter.

    lowercase token filter를 사용해, 단어를 소문자로 변경한다.

  5. Remove a custom list of stopwords, using a custom stop token filter:

    사용자 정의 stop token filter를 사용해, 사용자 정의 stopwords 목록을 제거한다.

    "filter": {
        "my_stopwords": {
            "type":        "stop",
            "stopwords": [ "the", "a" ]
        }
    }

Our analyzer definition combines the predefined tokenizer and filters with the custom filters that we have configured previously:

analyzer 정의는, 위에서 설정한 사용자 정의 filter와, 미리 정의된 tokenizer와 filter를 조합한 것이다.

"analyzer": {
    "my_analyzer": {
        "type":           "custom",
        "char_filter":  [ "html_strip", "&_to_and" ],
        "tokenizer":      "standard",
        "filter":       [ "lowercase", "my_stopwords" ]
    }
}

To put it all together, the whole create-index request looks like this:

이를 모두 같이 모으면, 전체 create-index request는 다음과 같다.

PUT /my_index
{
    "settings": {
        "analysis": {
            "char_filter": {
                "&_to_and": {
                    "type":       "mapping",
                    "mappings": [ "&=> and "]
            }},
            "filter": {
                "my_stopwords": {
                    "type":       "stop",
                    "stopwords": [ "the", "a" ]
            }},
            "analyzer": {
                "my_analyzer": {
                    "type":         "custom",
                    "char_filter":  [ "html_strip", "&_to_and" ],
                    "tokenizer":    "standard",
                    "filter":       [ "lowercase", "my_stopwords" ]
            }}
}}}

After creating the index, use the analyze API to test the new analyzer:

index를 생성한 후에, analyze API를 사용해, 새로운 analyzer를 테스트해 보자.

GET /my_index/_analyze
{
    "text": "The quick & brown fox",
    "analyzer": "my_analyzer"
}

The following abbreviated results show that our analyzer is working correctly:

결과는 analyzer가 올바르게 동작하고 있음을 보여준다.

{
  "tokens" : [
      { "token" :   "quick",    "position" : 2 },
      { "token" :   "and",      "position" : 3 },
      { "token" :   "brown",    "position" : 4 },
      { "token" :   "fox",      "position" : 5 }
    ]
}

The analyzer is not much use unless we tell Elasticsearch where to use it. We can apply it to a stringfield with a mapping such as the following:

Elasticsearch에서, 이 analyzer를 어디에서 사용할지를 지정하지 않으면, 아무런 쓸모가 없다. 아래처럼, string field에 mapping하여, 이 analyzer를 적용할 수 있다.

PUT /my_index/_mapping/my_type
{
    "properties": {
        "title": {
            "type":      "string",
            "analyzer":  "my_analyzer"
        }
    }
}


'2.X > 1. Getting Started' 카테고리의 다른 글

1-10-03. Index Settings  (0) 2017.09.30
1-10-04. Configuring Analyzers  (0) 2017.09.30
1-10-06. Types and Mappings  (0) 2017.09.30
1-10-07. The Root Object  (0) 2017.09.30
1-10-08. Dynamic Mapping  (0) 2017.09.30