본문 바로가기

빅데이터/Elasticsearch

엘라스틱서치에서 field 와 field.keyword 의 차이(text와 keyword)

엘라스틱서치와 키바나를 사용하여 데이터를 조회하다보면 아래와 같이 index pattern이 색인되어 있는것을 종종 볼 수 있습니다. field명이 그대로 나타나는 경우와 field.keyword로 나타나는 경우 입니다.

 

분명히 field명 key와 value(string)으로 넣었는데 둘의 차이가 무었일까요?

 

text와 keyword

엘라스틱서치 5버전 이후로는 string type은 textkeyword타입으로 변경되었습니다. 따로 명시적으로 mapping을 하지 않았다면 아래와 같이 엘라스틱서치에 들어가게 됩니다.

 

Input key/value :

{
  "some_field": "string value"
}

 

In elasticsearch:

{
  "some_field": {
    "type" "text",
    "fields": {
      "keyword": {
        "type": "keyword",
        "ignore_above": 256
      }
    }
  }
}

그래서 가장 처음에 나온 이미지와 같이 매핑되어 있는지는 엘라스틱서치에 curl명령어를 통해 확인할 수 있습니다.

$ curl -XGET http://엘라스틱서치:9200/인덱스/_mapping?pretty
{
  "인덱스" : {
    "mappings" : {
      "doc" : {
        "properties" : {
          "@timestamp" : {
            "type" : "date"
          },
          "@version" : {
            "type" : "text",
            "fields" : {
              "keyword" : {
                "type" : "keyword",
                "ignore_above" : 256
              }
            }
          },
          "client_id" : {
            "type" : "text",
            "fields" : {
              "keyword" : {
                "type" : "keyword",
                "ignore_above" : 256
              }
            }
          },
          ...
        }
      }
    }
  }
}

text와 keyword는 언제 사용할까?

text타입일 경우에는 형태소 기반으로 분리하기 때문에 단어형태로 검색할 경우 전문 검색이 가능합니다. 반면 keyword타입일 경우에는 exact value 즉, 완전 동일한 데이터에 대해 검색시 사용할 수 있습니다.

 

Example1 : Keyword타입인 경우

#1 mapping 정의
PUT products
{
  "mappings": {
    "_doc": {
      "properties": {
        "name": {
          "type": "keyword"
        }
      }
    }
  }
}

#2 insert value
POST products/_doc
{
  "name": "washing machine"
}

#3 search
GET products/_search
{
  "query": {
    "match": {
      "name": "washing"
    }
  }
}
// match doc 없음

위와 같이 keyword 타입인 경우 exact value가 아닌경우에는 단어가 포함되더라도 검색이 되지 않는 것으로 확인 됩니다.

 

Example2 : Text타입인 경우

#1 mapping 정의
PUT products
{
  "mappings": {
    "_doc": {
      "properties": {
        "name": {
          "type": "text"
        }
      }
    }
  }
}

#2 insert value
POST products/_doc
{
  "name": "washing machine"
}

#3 search
GET products/_search
{
  "query": {
    "match": {
      "name": "washing"
    }
  }
}
// match doc 존재

keyword type으로 mapping됬을때와 다르게 단어가 존재할 경우 검색되어 document를 return하는 것을 확인할 수 있습니다.

 

 

참고 url

- https://stackoverflow.com/questions/48869795/difference-between-a-field-and-the-field-keyword
- https://www.elastic.co/kr/blog/strings-are-dead-long-live-strings

- https://stackoverflow.com/questions/52845088/difference-between-keyword-and-text-in-elasticsearch

 

태그