ICU collation keyword 필드 타입

ICU collation keyword 필드 타입

icu_collation_keyword 필드 타입은 용어를 이진 인코딩된 collation 키로 저장해서, 언어별 정렬과 범위 쿼리를 가능하게 해요. 표준 문자열 정렬이 바이트 순서 비교를 사용하는 것과 달리, 이 필드 타입은 특정 언어나 로케일의 언어학적 규칙을 존중하는 collation 규칙을 적용해요.

이 필드 타입은 문서를 언어별 알파벳 순서로 정렬해야 하거나, 악센트가 있는 문자를 올바르게 처리해야 하거나, 문화적으로 적절한 문자열 비교를 구현해야 할 때 특히 유용해요.

출처: 문서

본문

설치 (Installation)

icu_collation_keyword 필드 타입은 analysis-icu 플러그인이 필요해요. 설치 방법은 ICU analyzer 문서를 참고하세요.

동작 방식 (How it works)

icu_collation_keyword 필드는 용어를 문서 값(doc value)에 직접 이진 collation 키로 인코딩하고 (표준 keyword 필드와 유사하게) 색인 토큰 하나를 만들어요. 이 접근 방식이 제공하는 이점은 다음과 같아요.

  • 언어 인지 정렬(Language-aware sorting): 특정 언어나 로케일에 특화된 collation 규칙을 적용해요.
  • 효율적인 저장(Efficient storage): 전체 문자열 대신 이진 collation 키를 저장해요.
  • 범위 쿼리 지원(Range query support): 언어학적 정렬 순서를 존중하는 범위 쿼리를 가능하게 해요.

기본적으로 이 필드는 DUCET(Default Unicode Collation Element Table) collation을 사용하며, 이는 언어 중립적으로 최선의 정렬 순서를 제공해요.

파라미터 (Parameters)

icu_collation_keyword 필드 타입이 받는 파라미터는 다음 표와 같아요.

파라미터 데이터 타입 설명
language String 언어 코드예요(예: 독일어는 de, 프랑스어는 fr). 선택 사항이에요.
country String 국가 코드예요(예: 독일은 DE, 프랑스는 FR). 선택 사항이에요.
variant String 추가 collation 옵션을 위한 변형 문자열이에요(예: 독일 전화번호부 순서를 위해 @collation=phonebook). 선택 사항이에요.
strength String collation 강도 수준이에요. 유효 값은 primary, secondary, tertiary, quaternary, identical이에요. 기본값은 tertiary예요. 선택 사항이에요.
decomposition String 문자 정규화 처리 방식이에요. 유효 값은 no와 canonical이에요. 기본값은 no예요. 선택 사항이에요.
alternate String 공백과 구두점 처리 방식이에요. 유효 값은 shifted와 non-ignorable이에요. 선택 사항이에요.
case_level Boolean strength가 primary일 때 대소문자 차이를 고려할지 여부예요. 기본값은 false예요. 선택 사항이에요.
case_first String 대문자와 소문자 중 무엇이 먼저 정렬될지예요. 유효 값은 lower와 upper이에요. 선택 사항이에요.
numeric Boolean 숫자 하위 문자열을 숫자 값으로 정렬할지 여부예요. 예를 들어 item-9가 item-21보다 먼저 정렬돼요. 기본값은 false예요. 선택 사항이에요.
variable_top String alternate 옵션에서 어떤 문자가 변수(variable)로 간주되는지 지정해요. 선택 사항이에요.
hiragana_quaternary_mode Boolean quaternary 강도에서 가타카나와 히라가나를 구분할지 여부예요. 선택 사항이에요.
doc_values Boolean 정렬과 집계를 위해 필드를 디스크에 저장할지 여부예요. 기본값은 true예요. 선택 사항이에요.
index Boolean 필드를 검색 가능하게 할지 여부예요. 기본값은 true예요. 선택 사항이에요.
null_value String 명시적인 null 값을 대체할 문자열 값이에요. 기본값은 null(필드가 없는 것으로 처리됨)이에요. 선택 사항이에요.
store Boolean 필드 값을 _source와 별도로 저장할지 여부예요. 기본값은 false예요. 선택 사항이에요.
fields Object 동일한 값을 다른 방식으로 색인하기 위한 멀티 필드 매핑이에요. 선택 사항이에요.

예시: 독일 전화번호부 정렬

다음 예시는 전화번호부 순서로 독일어 이름을 정렬하는 필드가 있는 인덱스를 만들어요.

PUT /german-names
{
  "mappings": {
    "properties": {
      "name": {
        "type": "text",
        "fields": {
          "sort": {
            "type": "icu_collation_keyword",
            "language": "de",
            "country": "DE",
            "variant": "@collation=phonebook"
          }
        }
      }
    }
  }
}

독일어 이름 몇 개를 색인해 볼게요.

POST /german-names/_bulk
{"index":{"_id":"1"}}
{"name":"Müller"}
{"index":{"_id":"2"}}
{"name":"Möller"}
{"index":{"_id":"3"}}
{"name":"Meyer"}
{"index":{"_id":"4"}}
{"name":"Schneider"}

collation 필드를 사용해 검색하고 정렬해 볼게요.

GET /german-names/_search
{
  "query": {
    "match_all": {}
  },
  "sort": "name.sort"
}

결과는 독일 전화번호부 규칙에 따라 정렬돼요. 여기서 ö와 ü는 독일 알파벳에서 서로 다른 문자로 취급돼요.

{
  "hits": {
    "total": {
      "value": 4,
      "relation": "eq"
    },
    "max_score": null,
    "hits": [
      {
        "_index": "german-names",
        "_id": "3",
        "_score": null,
        "_source": {
          "name": "Meyer"
        }
      },
      {
        "_index": "german-names",
        "_id": "2",
        "_score": null,
        "_source": {
          "name": "Möller"
        }
      },
      {
        "_index": "german-names",
        "_id": "1",
        "_score": null,
        "_source": {
          "name": "Müller"
        }
      },
      {
        "_index": "german-names",
        "_id": "4",
        "_score": null,
        "_source": {
          "name": "Schneider"
        }
      }
    ]
  }
}

예시: 프랑스어 악센트 문자 정렬

다음 예시는 프랑스어 linguistic 규칙에 따라 악센트가 있는 문자를 처리하는 프랑스어 collation을 보여줘요.

PUT /french-words
{
  "mappings": {
    "properties": {
      "word": {
        "type": "text",
        "fields": {
          "sort": {
            "type": "icu_collation_keyword",
            "language": "fr",
            "country": "FR",
            "strength": "primary"
          }
        }
      }
    }
  }
}

악센트가 있는 프랑스어 단어를 색인해 볼게요.

POST /french-words/_bulk
{"index":{"_id":"1"}}
{"word":"cote"}
{"index":{"_id":"2"}}
{"word":"côte"}
{"index":{"_id":"3"}}
{"word":"coté"}
{"index":{"_id":"4"}}
{"word":"côté"}

정렬과 함께 쿼리해 볼게요.

GET /french-words/_search
{
  "query": {
    "match_all": {}
  },
  "sort": "word.sort"
}

결과는 프랑스어 알파벳 규칙을 따르게 돼요.

Collation 강도 수준 (Collation strength levels)

strength 파라미터는 collation이 문자열을 얼마나 엄격하게 비교할지 결정해요.

  • primary: 기본 문자만 비교하고 악센트와 대소문자는 무시해요. 예를 들어 a, A, á, Á는 모두 동등하게 취급돼요.
  • secondary: 기본 문자와 악센트를 비교하지만 대소문자는 무시해요. 예를 들어 a와 á는 다르지만, a와 A는 동등해요.
  • tertiary (기본값): 기본 문자, 악센트, 대소문자를 모두 비교해요. 예를 들어 a, A, á는 모두 서로 달라요.
  • quaternary: alternate가 shifted로 설정되어 있을 때 구두점과 공백 비교를 추가해요.
  • identical: 문자 단위 이진 비교를 수행해요.

성능 고려 사항 (Performance considerations)

icu_collation_keyword 필드 타입은 표준 keyword 필드보다 이진 collation 키를 저장하기 때문에 더 많은 디스크 공간을 사용해요. 하지만 이 접근 방식은 쿼리 시점에 collation을 적용하는 것보다 정렬과 범위 쿼리를 더 빠르게 수행해요.

최적의 성능을 위해 이렇게 해보세요.

  • icu_collation_keyword를 기본 필드 타입보다는 text 필드의 멀티 필드로 사용해요.
  • collation 필드에서 정렬만 필요하고 범위 쿼리는 필요 없다면 index: false로 설정해요.
  • 적절한 강도 수준을 선택해요. 강도가 낮을수록 collation 키가 더 작아져요.
  • ICU analyzer
  • Keyword field type
  • Sorting results

더 알아보기 (Learn more)