Elasticsearch에서 특수문자를 포함한 `categoryName` 필드 검색 문제 해결

이경헌·2025년 4월 19일
0

문제 설명

Elasticsearch를 사용하여 게시물 데이터를 검색하는 애플리케이션에서 categoryName을 필터링하는 기능을 구현 중이었습니다. 그런데, categoryName/, &, # 등 특수문자가 포함된 값들이 검색되지 않는 문제가 발생했습니다. 이 문제는 주로 필드 타입에 따라 발생하는 문제로, Text 타입으로 설정된 필드는 분석(Analyzing)을 거치기 때문에 특수문자가 제대로 처리되지 않아 발생하는 경우가 많습니다.

원인 분석

Elasticsearch에서 Text 타입 필드는 기본적으로 텍스트 분석을 거칩니다. 이때, 특수문자나 공백을 기준으로 단어를 분리하거나 토큰화하는 과정에서 특수문자가 사라지거나 변형되어 검색되지 않는 경우가 발생합니다. 이를 해결하기 위해서는 필드에 대해 분석하지 않는 방식인 Keyword 타입을 사용하는 것이 좋습니다.

해결 방법

1. 필드 타입 변경

기존에 categoryName 필드는 Text 타입으로 되어 있었습니다. 이 필드를 Keyword 타입으로 변경하여, 특수문자와 공백을 포함한 값들이 그대로 저장되도록 설정합니다.

기존 코드

@Field(type = FieldType.Text)
private String categoryName;

변경 코드

@Field(type = FieldType.Keyword)
private String categoryName;

Keyword 타입은 분석을 하지 않고, 입력된 값을 그대로 저장하므로 특수문자도 정확히 검색할 수 있습니다.

2. 쿼리

boolQuery.filter(f -> f
    .terms(t -> t
        .field("categoryName")
        .terms(v -> v.value(categoryFieldValues))
    )
);

3. 매핑 변경

Elasticsearch에서 이미 데이터가 저장되어 있는 경우, 매핑을 수정하는 것만으로는 기존 데이터에 영향을 미치지 않습니다. 기존에 Text 타입으로 저장된 categoryName 데이터를 Keyword 타입으로 변경하려면 새로운 인덱스를 생성하고 데이터를 마이그레이션해야 합니다. 이는 Elasticsearch의 재색인(Reindex) 기능을 통해 수행할 수 있습니다.

PUT /new-post-index
{
  "mappings": {
    "properties": {
      "categoryName": {
        "type": "keyword"
      }
    }
  }
}

결론

  • Elasticsearch에서 특수문자가 포함된 값을 정확히 검색하기 위해서는, Text 필드를 Keyword로 변경해야 합니다. 또한, 필드 매핑을 변경한 후에는 재색인을 통해 기존 데이터를 새로운 인덱스로 마이그레이션해야 할 수 있습니다. 이러한 방법을 통해 특수문자 문제를 해결하고, 정확한 검색 결과를 얻을 수 있습니다.

  • Text 필드의 경우에는 분석기가 데이터를 분석하여 토큰화하고, 분석된 값이 실제로 저장됩니다.

  • Keyword 필드의 경우에는 분석기가 없이 그대로 저장되며, 이 필드는 분석을 하지 않고 저장되는 값이 그대로 사용됩니다.


0개의 댓글