초 간단 비교)
- 둘 다 searchable 합니다.
- keyword 는 형태소 분석을 하지 않습니다. (not analyzed)
- text 는 형태소 분석을 합니다. (analyzed)
시작 하기에 앞서 먼저 공홈에서 제공하는 레퍼런스 부터 보시죠.
[Keyword]
https://www.elastic.co/guide/en/elasticsearch/reference/current/keyword.html
[Text]
https://www.elastic.co/guide/en/elasticsearch/reference/current/text.html
사실 위 문서만 자세히 읽어 보셔도 두 필드의 용도와 차이점이 어떻게 되는지는 쉽게 아실 수 있습니다.
다만, 사용하다 보면 놓치는 부분이 발생을 하는데 여기서는 제가 놓친 부분에 대해서 같은 실수를 하지 않기 위해 글로 남겨 보려 합니다.
keyword 는 기본적으로 exact value 입니다.
문서에서는 이렇게 표현 하고 있습니다.
They are typically used for filtering (Find me all blog posts where status is published), for sorting, and for aggregations. Keyword fields are only searchable by their exact value.
- filtering
- sorting
- aggregations
- searchable
- exact value
이 내용만 보시면 어떤 부분이 빠져 있다는 걸 알아채셔야 합니다.
결과적으로 말씀 드리면, 검색에 대한 내용만 있고 색인에 대한 내용은 빠져 있습니다.
색인에 대한 내용은 사실 문서의
https://www.elastic.co/guide/en/elasticsearch/reference/current/keyword.html#keyword-params
이 부분을 보시면 되긴 합니다.
하지만 이 내용을 보더라도 쉽게 놓칠 수 있는 부분이 있습니다.
바로 형태소 분석이 어떻게 이루어 지느냐 입니다.
기본 analyzer 설정을 하지 않으면 standard analyzer 로 지정이 됩니다.
이 analyzer 는 기본적으로 lowercase filter 적용이 되어 있습니다.
그럼 keyword field 의 value 는 모두 lowercase filter 적용이 되겠지요?
뭐 아시겠지만 lowercase filter 적용이 되지 않습니다.
parameter 설정을 찾아 보셔서 아시겠지만 analyzer 설정 하는 내용이 없습니다.
text 의 경우 per field analyzer 설정이 가능 합니다.
하지만 keyword 는 설정을 할 수가 없습니다.
이 말은 keyword field 의 value 는 입력 상태 그대로의 값이 저장 된다고 보시면 됩니다.
별도의 token filter 적용이 되지 않는 다는 것입니다.
[KeywordFieldMapper]
public static class Defaults {
public static final MappedFieldType FIELD_TYPE = new KeywordFieldType();
static {
FIELD_TYPE.setTokenized(false);
FIELD_TYPE.setOmitNorms(true);
FIELD_TYPE.setIndexOptions(IndexOptions.DOCS);
FIELD_TYPE.freeze();
}
public static final String NULL_VALUE = null;
public static final int IGNORE_ABOVE = Integer.MAX_VALUE;
}
여기서 그럼 이 야기를 왜 하는 것일까요?
한글은 대소문자 구분이 없어서 상관 없지만 영문자와 같은 경우 대소문자 구분이 된다는 이야기를 드리기 위해서 이렇게 서론이 길었습니다.
결론)
Keyword 필드의 Value 는 Token filter 적용이 되지 않습니다.
대소문자 구분에 주의 해서 사용 하셔야 합니다.