RDBMS를 사용하다가 Elasticsearch에서 쿼리를 작성하면서 wildcard를 사용한 쿼리의 결과가 제가 생각했던 것과 달라서, 해당 내용에 대해 충분히 이해하기 위해 글을 작성하려고 합니다. Wildcard query를 작성하면서 예상했던 결과는 RDBMS의 LIKE에서 사용했던 '%searchInput%'와 같은 형태가 가능할 것으로 기대했는데, 막상 확인되는 결과는 그렇지 않았습니다.
원본 텍스트는 "경기도 용인시 기흥구 중동 1100번지"와 같은 형태의 주소입니다. 제가 시도한 쿼리는 다음과 같았습니다.
{
"query": {
"bool": {
"must": [
{
"wildcard": {
"address": {
"value": "*경기도 기흥구*"
}
}
}
]
}
}
}
그런데 결과는 아래와 같이 hits count가 0이었습니다. 😂
{
"took" : 15,
"timed_out" : false,
"_shards" : {
"total" : 1,
"successful" : 1,
"skipped" : 0,
"failed" : 0
},
"hits" : {
"total" : {
"value" : 0,
"relation" : "eq"
},
"max_score" : null,
"hits" : [ ]
}
}
Elasticsearch에서 Wildcard 쿼리의 작동 방식
그렇다면 Elasticsearch에서 사용하는 wildcard query는 무엇이 다를까요? 🤔
Elasticsearch에서의 wildcard query는 term level query입니다. Term level query란 무엇일까요? 😟
Term query는 inverted index를 기준으로 결과를 찾는다는 의미이며, 이는 분석(analyzed)된 term keyword가 있어야 함을 의미합니다. 문서를 색인할 때 토크나이징된 단어가 아니라면 inverted index에 포함되지 않기 때문에, 아예 비교 대상에 포함되지 않는 것입니다.
제가 테스트한 custom analyzer의 토크나이징은 아래와 같았습니다.
POST /test_index/_analyze
{
"field": "address",
"text": "경기도 용인시 기흥구 중동 1100번지"
}
토크나이징 결과
{
"tokens" : [
{
"token" : "경기도",
"start_offset" : 0,
"end_offset" : 3,
"type" : "<HANGUL>",
"position" : 0
},
{
"token" : "용인시",
"start_offset" : 4,
"end_offset" : 7,
"type" : "<HANGUL>",
"position" : 1
},
{
"token" : "기흥구",
"start_offset" : 8,
"end_offset" : 11,
"type" : "<HANGUL>",
"position" : 2
},
{
"token" : "중동",
"start_offset" : 12,
"end_offset" : 14,
"type" : "<HANGUL>",
"position" : 3
},
{
"token" : "1100번지",
"start_offset" : 15,
"end_offset" : 21,
"type" : "<ALPHANUM>",
"position" : 4
}
]
}
토크나이징된 결과에 *경기도 기흥구*라는 단어는 없기 때문에, 처음 질의한 wildcard 결과가 hits가 0일 수밖에 없었던 것입니다. 🫠
올바른 Wildcard 쿼리 작성 방법
따라서, 올바른 쿼리를 작성하기 위해서는 특정 토큰을 기준으로 조회해야 합니다.
{
"query": {
"bool": {
"must": [
{
"wildcard": {
"address": {
"value": "*경기도*"
}
}
},
{
"wildcard": {
"address": {
"value": "*기흥구*"
}
}
}
]
}
}
}
Wildcard 쿼리는 성능이 좋지 않을 수 있으며, 특히 앞에 와일드카드가 있는 경우(예: *경기도) 전체 문서 검색을 수행하게 되어 시간이 오래 걸릴 수 있으므로, 쿼리의 효율성을 높이기 위해서는 검색할 토큰을 명확히 설정하고, 필요에 따라 데이터에 적합한 사용자 정의 분석기를 설정하여 검색 성능을 개선하는 것이 중요합니다.
'DevOps > Elastic Stack' 카테고리의 다른 글
[Elasticsearch] 성능 향상을 위한 doc_values 사용법: 메모리 효율 향상시키기 - 컴도리돌이 (3) | 2024.11.09 |
---|---|
[Elasticsearch] 성능 개선을 위한 코드 비교 및 분석 - 컴도리돌이 (4) | 2024.11.08 |
[ELK] 인덱스(생성/조회/삭제)와 도큐먼트(CRUD)에 대해서 - 컴도리돌이 (0) | 2024.01.23 |
[Elasticsearch] 엘라스틱 서치 역인덱스(Elasticsearch inverted index) - 컴도리돌이 (0) | 2024.01.17 |
[ELK] Elastic Stack에 대해서 - 컴도리돌이 (2) | 2024.01.16 |