공홈 레퍼런스 문서)
https://www.elastic.co/guide/en/elasticsearch/reference/8.5/term-level-queries.html
https://www.elastic.co/guide/en/elasticsearch/reference/8.5/normalizer.html
한 줄 요약)
Keyword field 의 경우 normalizer 선언을 할 경우 index analyzer 뿐만 아니라 search analyzer 에도 동일하게 적용 됩니다.
보통 Keyword field 사용 시 term level query 를 사용하게 되면 검색어에 대한 형태소 분석 없이 token 에 대한 exact matching 을 한다고 가정 하게 됩니다.
이 경우에 해당 하기 위해서는 keyword field 선언 시 normalizer 선언이 없어야 적용이 됩니다.
아래는 관련 코드에 대해서 일부 snippet 한 내용입니다.
NamedAnalyzer normalizer = Lucene.KEYWORD_ANALYZER;
NamedAnalyzer searchAnalyzer = Lucene.KEYWORD_ANALYZER;
NamedAnalyzer quoteAnalyzer = Lucene.KEYWORD_ANALYZER;
String normalizerName = this.normalizer.getValue();
KeywordFieldMapper 클래스에 선언된 코드 입니다.
보시면 기본 Search Analyzer 는 Keyword Analyzer 입니다.
...중략...
searchAnalyzer = quoteAnalyzer = normalizer;
...중략...
코드 중간에 들어가 보면 이와 같이 선언 된 것을 보실 수 있습니다.
그리고 노말라이저 선언이 없으면
searchAnalyzer = Lucene.WHITESPACE_ANALYZER;
Whitespace Analyzer 로 선언 되는 것도 확인이 가능 합니다.
보시면 아시겠지만 기본적으로 Keyword type 에 선언 되는 Search Analyzer 는 Lucene.KEYWORD_ANALYZER 로 선언 되게 되어 있습니다.
즉, Normalizer 선언이 없으면 기본이 키워드 인거죠. 그래서 별도 형태소 분석 과정이 없다보 인식 하는 건데 사실 없다고 보기 어렵고 Keyword Analyzer 의 Token Filter 를 따른다고 이해 하는게 맞습니다.
https://www.elastic.co/guide/en/elasticsearch/reference/current/analysis-keyword-analyzer.html
이 분석기는 아무런 선언을 하지 않으면 noop 에 정확히 텍스트가 일치해야 하는 분석기 입니다.
근데 색인 시점에 whitespace 를 포함한 텍스트를 keyword 로 선언 하고 이걸 whitespace 로 토큰 분해 하고 싶을 경우 "split_queries_on_whitespace" 이 옵션을 true 로 해주시면 됩니다.
그럼 KeywordAnalyzer/Tokenizer 이넘의 기본 형태소 분석은 그냥 텍스트를 하나의 토큰으로 분석 한다고 이해 하시면 되겠습니다.
여기서 whitespace 단위로 분해하고 싶으면 바로 위에 옵션 활용, 그리고 normalizer 는 토큰에 적용 되는데 search analyzer 에 반영 된다는 걸 기억 하면 됩니다.
문서에 나와 있던 내용 그대로 이고요. 코드 상으로는 어떻게 되어 있을까 궁금해서 찾아본 내용 공유 드립니다. ^^
보셔야 하는 클래스는
- KeyowrdFieldMapper
- KeywordAnalyzer
- KeywordTokenizer