2.X/3. Dealing with Human Language

3-1-1. Using Language Analyzers

drscg 2017. 9. 24. 17:56

The built-in language analyzers are available globally and don’t need to be configured before being used. They can be specified directly in the field mapping:

내장된 language analyzer는 범용적으로 이용할 수 있고, 사용하기 전에 설정할 필요가 없다. field mapping에서 바로 지정할 수 있다.

PUT /my_index
{
  "mappings": {
    "blog": {
      "properties": {
        "title": {
          "type":     "string",
          "analyzer": "english" 
        }
      }
    }
  }
}

title field는, 기본값인 standard analyzer 대신에, english analyzer를 사용한다.

Of course, by passing text through the english analyzer, we lose information:

물론, 문장(text)은 english analyzer를 통과하면, 의미를 잃어버린다.

GET /my_index/_analyze?field=title 
I'm not happy about the foxes

출력된 token: i'mhappiaboutfox

We can’t tell if the document mentions one fox or many foxes; the word not is a stopword and is removed, so we can’t tell whether the document is happy about foxes or not. By using the englishanalyzer, we have increased recall as we can match more loosely, but we have reduced our ability to rank documents accurately.

document에 언급된 것이, 단수 fox 인지, 복수 foxes 인지 알 수 없다. not 이라는 단어는 불용어(stopwords)라 제거된다. 따라서 document가 fox 에 대해 happy 인지 아닌지 알 수 없다. englishanalyzer를 사용함으로써, 더 느슨하게 일치할 수 있어, recall이 증가한다. 그러나 document를 정확하게 정렬하는 능력은 줄어들었다.

To get the best of both worlds, we can use multifields to index the title field twice: once with the english analyzer and once with the standard analyzer:

양쪽 모두를 얻기 위해, title field를 두 번 색인(english analyzer와 standard analyzer로 각각 한번씩)하는 다중 field를 사용할 수 있다.

PUT /my_index
{
  "mappings": {
    "blog": {
      "properties": {
        "title": { 
          "type": "string",
          "fields": {
            "english": { 
              "type":     "string",
              "analyzer": "english"
            }
          }
        }
      }
    }
  }
}

title field는 standard analyzer를 사용한다.

title.english field는 english analyzer를 사용한다.

With this mapping in place, we can index some test documents to demonstrate how to use both fields at query time:

이 mapping이 준비가 되면, query시에 두 field를 사용하는 방법을 테스트하기 위해, 몇 개의 document를 색인할 수 있다.

PUT /my_index/blog/1
{ "title": "I'm happy for this fox" }

PUT /my_index/blog/2
{ "title": "I'm not happy about my fox problem" }

GET /_search
{
  "query": {
    "multi_match": {
      "type":     "most_fields", 
      "query":    "not happy foxes",
      "fields": [ "title", "title.english" ]
    }
  }
}

가능한 한 많은 field에 동일한 텍스트가 일치하도록 most_fields query type을 사용한다.

Even though neither of our documents contain the word foxes, both documents are returned as results thanks to the word stemming on the title.english field. The second document is ranked as more relevant, because the word not matches on the title field.

document 모두가 foxes 라는 단어를 포함하지 않지만, title.english field의 형태소 분석된 단어 덕분에, 두 document 모두가 결과로서 반환된다. 그리고, not 이라는 단어가 title field에 일치하기 때문에, 두 번째 document가 더 관련 있는 것으로 정렬된다.