엘라스틱서치 이용 중 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"
}
}
}
}