엘라스틱서치 버그문자(�)가 낀 문서 지우기

Jake Seo·2020년 4월 6일
2

Elasticsearch

목록 보기
3/4

문제

엘라스틱서치 이용 중 Document의 내용에 '�' 이렇게 생긴 버그문자가 들어가는 현상이 생겼다. 또 그 버그문자는 a라는 필드의 내부에 있는 b라는 필드에 들어있다.

전체 버그 문서의 내용은 대략 '��醫�肄�濡���' ���� ��珥��� 465紐� 寃⑸━����' 이런 내용이 들어있다.

정리하자면, 중첩된 필드 내부에 있는 특정 문자(�)가 포함된 모든 Document를 지우고 싶을 때 는 어떻게 해야 할까?

문제 해결 시도

아마, 쿼리에 해당하는 모든 도큐먼트를 지워주는 DeleteByQuery 기능을 이용하여 지우면 될 것 같다는 생각을 했고,

해당되는 내용을 검색하는 쿼리를 짜려고 했다. match 쿼리를 이용해보았다.

GET index/_search
{
    "query": {
        "match" : {
            "a.b": {
                "query" : "�"
            }
        }
    }
}

위와 같이 해봤지만, 제대로 검색되지 않았다. 검색되지 않는 이유가 무엇인지 알아보기 위해서 analyzer에 저 문자를 넣어봤는데,

결과가 아래와 같이 나왔다.

그 이유는 엘라스틱서치 field에 붙은 analyzer(nori)가 "�"문자 자체를 인식하지 못하기 때문인 것 같다. 고로 이건 analyzer를 거치지 않고 Raw한 데이터를 검색하는 방법으로 수행해야 한다는 결론이 났다.

하지만....

text로 매핑된 필드에서 Raw한 데이터를 기반으로 검색하는 방법은 찾아도 찾아도 안 나왔다. 애초에 Elasticsearch는 다른 검색엔진과 같이 색인을 기반으로 검색하는 검색엔진이고, 어떤 기준으로 색인을 할지는 analyzer에서 정한다. text로 매핑된 필드에서는 analyzer가 정한 나름의 토크나이징을 기준으로 색인을 한다. 그래서 저렇게 토크나이징할 때 아예 사라져버리는 글자에 대해서는 검색이 불가능하다.

저런 것들도 검색을 가능하게 하려면, keyword 매핑도 같이 주어야 하나보다. keyword 매핑에서는 실험 결과 잘 검색된다.

keyword 매핑에서 검색할 때는 다음과 같이 검색하면 된다.

GET index/_search
{
    "query": {
        "wildcard": {
            "field": {
                "value": "*�*",
                "boost": 1.0,
                "rewrite": "constant_score"
            }
        }
    }
}

지울 때는, 요청 정보만 바꿔서 아래와 같이 입력해주자.

POST index/_delete_by_query
{
    "query": {
        "wildcard": {
            "field": {
                "value": "*�*",
                "boost": 1.0,
                "rewrite": "constant_score"
            }
        }
    }
}

결론

  1. text로만 매핑된 필드에서 analyzer가 토크나이징 하지 못하는 문자(�)는 검색할 수도 없다.
  2. 그래서 애초에 필드를 만들 때, keyword와 text 매핑을 둘 다 주는 것이 좋다.
  3. keyword필드라면 위에 기재된 것과 같은 와일드 카드 쿼리로 검색하여 지우면 된다.
profile
풀스택 웹개발자로 일하고 있는 Jake Seo입니다. 주로 Jake Seo라는 닉네임을 많이 씁니다. 프론트엔드: Javascript, React 백엔드: Spring Framework에 관심이 있습니다.

0개의 댓글