5.5 정확값 쿼리 - Exact Value Query
이 문서의 허가되지 않은 무단 복제나 배포 및 출판을 금지합니다. 본 문서의 내용 및 도표 등을 인용하고자 하는 경우 출처를 명시하고 김종민([email protected])에게 사용 내용을 알려주시기 바랍니다.
지금까지 살펴본 풀 텍스트 검색은 스코어 점수 기반으로 정확도(relevancy)가 높은 결과부터 가져옵니다. Elasticsearch는 정확도를 고려하는 풀 텍스트 외에도 검색 조건의 참 / 거짓 여부만 판별해서 결과를 가져오는 것이 가능합니다. 풀 텍스트와 상반되는 이 특성을 정확값(Exact Value) 이라고 하는데 말 그대로 값이 정확히 일치 하는지의 여부 만을 따지는 검색입니다. Exact Value 에는 term, range 와 같은 쿼리들이 이 부분에 속하며, 스코어를 계산하지 않기 때문에 보통 bool 쿼리의 filter 내부에서 사용하게 됩니다.
bool : filter
bool쿼리의 filter 안에 하위 쿼리를 사용하면 스코어에 영향을 주지 않습니다. 다음 3개의 검색 결과를 비교 해 보도록 하겠습니다.
GET my_index/_search
{
"query": {
"match": {
"message": "fox"
}
}
}{
"took" : 1,
"timed_out" : false,
"_shards" : {
"total" : 1,
"successful" : 1,
"skipped" : 0,
"failed" : 0
},
"hits" : {
"total" : {
"value" : 4,
"relation" : "eq"
},
"max_score" : 0.32951736,
"hits" : [
{
"_index" : "my_index",
"_type" : "_doc",
"_id" : "1",
"_score" : 0.32951736,
"_source" : {
"message" : "The quick brown fox"
}
},
{
"_index" : "my_index",
"_type" : "_doc",
"_id" : "4",
"_score" : 0.32951736,
"_source" : {
"message" : "Brown fox brown dog"
}
},
{
"_index" : "my_index",
"_type" : "_doc",
"_id" : "2",
"_score" : 0.23470737,
"_source" : {
"message" : "The quick brown fox jumps over the lazy dog"
}
},
{
"_index" : "my_index",
"_type" : "_doc",
"_id" : "3",
"_score" : 0.23470737,
"_source" : {
"message" : "The quick brown fox jumps over the quick dog"
}
}
]
}
}GET my_index/_search
{
"query": {
"bool": {
"must": [
{
"match": {
"message": "fox"
}
},
{
"match": {
"message": "quick"
}
}
]
}
}
}{
"took" : 1,
"timed_out" : false,
"_shards" : {
"total" : 1,
"successful" : 1,
"skipped" : 0,
"failed" : 0
},
"hits" : {
"total" : {
"value" : 3,
"relation" : "eq"
},
"max_score" : 0.9468958,
"hits" : [
{
"_index" : "my_index",
"_type" : "_doc",
"_id" : "1",
"_score" : 0.9468958,
"_source" : {
"message" : "The quick brown fox"
}
},
{
"_index" : "my_index",
"_type" : "_doc",
"_id" : "3",
"_score" : 0.8762741,
"_source" : {
"message" : "The quick brown fox jumps over the quick dog"
}
},
{
"_index" : "my_index",
"_type" : "_doc",
"_id" : "2",
"_score" : 0.6744513,
"_source" : {
"message" : "The quick brown fox jumps over the lazy dog"
}
}
]
}
} 첫번째는 match 쿼리로 fox 를 검색했을 때 4개의 도큐먼트가 검색되었고 가장 높은 스코어는 "_score" : 0.32951736 입니다. 두번째는 검색에 match 쿼리로 quick 을 추가했을 때 3개의 도큐먼트가 검색되었고 가장 높은 스코어는 "_score" : 0.9468958 입니다. 세번째는 첫번째의 검색에 filter 구문 안에 quick 을 추가했는데 3개의 도큐먼트가 검색되었고 가장 높은 스코어는 첫번째 쿼리와 같은 "_score" : 0.32951736 입니다.
이렇게 filter는 검색에 조건은 추가하지만 스코어에는 영향을 주지 않도록 제어할 때 사용합니다. 보통 쇼핑몰에서 검색어로 정확도가 높은 상품명을 검색하면서 생산 업체를 다시 필터링 하는 등의 용도로 사용이 가능합니다.
filter 내부에서 must_not 과 같은 다른 bool 쿼리를 포함하려면 filter 내부에 bool 쿼리를 먼저 넣고 그 안에 다시 must_not 을 넣어야 합니다. 다음은 fox 를 포함하면서 dog 는 포함하지 않는 도큐먼트를 검색하는 쿼리입니다. dog 를 제외하는 must_not 쿼리가 filter 안에 있기 때문에 스코어는 fox 에만 영향을 받습니다.
위 검색에서 결과는 하나만 리턴 되었지만 스코어는 "_score" : 0.32951736으로 match 쿼리로 fox만 검색했을 때의 결과와 동일합니다.
keyword
문자열 데이터는 keyword 형식으로 저장하여 정확값 검색이 가능합니다. Keyword 에 대해서는 뒤에 매핑에서 다시 설명 하겠습니다. 아래의 쿼리는 message 필드값이 "Brown fox brown dog" 문자열과 공백, 대소문자까지 정확히 일치하는 데이터만을 결과로 리턴합니다.
keyword 타입으로 저장된 필드는 스코어를 계산하지 않고 정확값의 일치 여부만을 따지기 때문에 스코어가 "_score" : 0.0 으로 나오게 됩니다. 스코어를 계산하지 않기 때문에 keyword 값을 검색 할 때는 filter 구문 안에 넣도록 합니다.
Last updated
Was this helpful?