7.2.1 문자열 - text, keyword

이 문서의 허가되지 않은 무단 복제나 배포 및 출판을 금지합니다. 본 문서의 내용 및 도표 등을 인용하고자 하는 경우 출처를 명시하고 김종민(kimjmin@gmail.com)에게 사용 내용을 알려주시기 바랍니다.

Elasticsearch 에서 선언이 가능한 문자열 타입에는 text, keyword 두 가지가 있습니다. 2.x 버전 이전에 문자열은 string 이라는 하나의 타입만 있었고 텍스트 분석 여부, 즉 애널라이저 적용을 할 것인지 아닌지를 구분하는 설정이 있었습니다. 5.0 버전 부터는 텍스트 분석의 적용 여부를 text 타입과 keyword 타입으로 구분을 합니다. 인덱스를 생성할 때 매핑에 필드를 미리 정의하지 않으면 동적 문자열 필드가 생성 될 때 text 필드와 keyword 필드가 다중 필드로 같이 생성됩니다.

text

text 타입은 입력된 문자열을 텀 단위로 쪼개어 역 색인 (inverted index) 구조를 만듭니다. 보통은 풀텍스트 검색에 사용할 문자열 필드 들을 text 타입으로 지정합니다. text 필드에 설정 가능한 옵션들은 다음과 같은 것들이 있습니다.

  • "analyzer" : "<애널라이저명>" - 색인에 사용할 애널라이저를 입력하며 디폴트로는 standard 애널라이저를 사용합니다. 토크나이저, 토큰필터들을 따로 지정할수가 없으며 필요하다면 사용자 정의 애널라이저를 settings에 정의 해 두고 사용합니다.

  • "search_analyzer" : "<애널라이저명>" - 기본적으로 text 필드는 match 쿼리로 검색을 할 때 색인에 사용한 동일한 애널라이저로 검색 쿼리를 분석합니다. search_analyzer 를 지정하면 검색시에는 색인에 사용한 애널라이저가 아닌 다른 애널라이저를 사용합니다. 보통 NGram 방식으로 색인을 했을 때는 지정 해 주는 것이 바람직합니다.

  • "index" : <true | false> - 디폴트는 true 입니다. false로 설정하면 해당 필드는 역 색인을 만들지 않아 검색이 불가능하게 됩니다.

  • "boost" : <숫자 값> - 디폴트는 1 입니다. 값이 1 보다 높으면 풀텍스트 검색 시 해당 필드 스코어 점수에 가중치를 부여합니다. 1보다 낮은 값을 입력하면 가중치가 내려갑니다.

  • "fielddata" : <true | false> - 디폴트는 false 입니다. true로 설정하면 해당 필드의 색인된 텀 들을 가지고 집계(aggregation) 또는 정렬(sorting)이 가능합니다. 이 설정은 다이나믹 설정으로 이미 정의된 매핑에 true 또는 false로 다시 적용하는 것이 가능합니다.

"fielddata": true 설정이 되면 쿼리에 메모리 사용량이 많아지기 때문에 일반적으로는 권장하지 않는 옵션입니다. 그리고 모든 텀 들은 애널라이저가 적용되어 처리된 형태로 집계나 정렬에 사용되기 때문에 특히 정렬 같은 경우 일반적으로 예상하는 정렬과 결과가 다르게 나오는 경우가 많습니다. 집계와 정렬은 항상 keyword 필드로 사용하는 것을 권장합니다.

keyword

keyword 타입은 입력된 문자열을 하나의 토큰으로 저장합니다. text 타입에 keyword 애널라이저를 적용 한 것과 동일합니다. 보통은 집계(aggregation) 또는 정렬(sorting)에 사용할 문자열 필드를 keyword 타입으로 지정합니다. keyword 필드에 설정 가능한 옵션들은 다음과 같은 것들이 있습니다.

  • index, boost 설정은 text 필드와 동일하게 동작합니다.

  • "doc_values" : <true | false> - 디폴트는 true 입니다. keyword 값들은 기본적으로 집계나 정렬에 메모리를 소모하지 않기 위해 값들을 doc_values 라고 하는 별도의 열 기반 저장소(columnar store)를 만들어 저장합니다. 이 값을 false로 하면 doc_values에 값을 저장하지 않아 집계나 정렬이 불가능해집니다.

  • "ignore_above" : <자연수> - 디폴트는 2,147,483,647 이며 다이나믹 매핑으로 생성되면 ignore_above: 256 로 설정이 됩니다. 설정된 길이 이상의 문자열은 색인을 하지 않아 검색이나 집계가 불가능합니다. _source에는 남아있기 때문에 다른 필드 값을 쿼리해서 나온 결과로 가져오는 것은 가능합니다.

  • "normalizer" : "<노멀라이저명>" - keyword 필드는 애널라이저를 사용하지 않는 대신 노멀라이저(normalizer) 의 적용이 가능합니다. 노멀라이저는 애널라이저와 유사하게 settings 에서 정의하며 토크나이저는 적용할 수 없고 캐릭터 필터와 토큰 필터만 적용해서 사용이 가능합니다.

다음은 앞에서 살펴본 text, keyword의 옵션들을 다양하게 사용해서 blogs 인덱스를 정의하는 예제입니다. 각각의 옵션들이 어떤 필드에 어떻게 사용이 되었고, 명시된 각 필드들이 어떻게 동작을 할지 한번 짐작 해 보시기 바랍니다.

blogs 인덱스 선언하면서 각 필드의 text, keyword 매핑 설정
PUT blogs
{
  "settings": {
    "analysis": {
      "analyzer": {
        "engram_a": {
          "tokenizer": "standard",
          "filter": [ "lowercase", "engram_f" ]
        }
      },
      "filter": {
        "engram_f": {
          "type": "edge_ngram",
          "min_gram": 2,
          "max_gram": 5
        }
      },
      "normalizer": {
        "norm_low": {
          "type": "custom",
          "filter": [ "lowercase", "asciifolding" ]
        }
      }
    }
  },
  "mappings": {
    "properties": {
      "title": {
        "type": "text",
        "boost": 2,
        "fields": {
          "keyword": {
            "type": "keyword",
            "normalizer": "norm_low"
          }
        }
      },
      "author": {
        "type": "text",
        "analyzer": "engram_a",
        "search_analyzer": "standard",
        "fields": {
          "keyword": {
            "type": "keyword",
            "ignore_above": 256
          }
        }
      },
      "synopsis": {
        "type": "text",
        "fielddata": true
      },
      "category": {
        "type": "keyword"
      },
      "content": {
        "type": "text",
        "index": false
      }
    }
  }
}

지금까지 text와 keyword의 주요 설정에 대해 살펴보았습니다. 이 외에도 추가적으로 지정 가능한 다른 설정들이 있으니 공식 도큐먼트에서 확인 해 보시기 바랍니다.

Last updated