본문 바로가기

공부방/Elasticsearch

정확값 쿼리 (Exact Value Query)

지금까지 살펴본 풀 텍스트 검색은 스코어 점수 기반으로 정확도(relevancy)가 높은 결과부터 가져옵니다.

Elasticsearch는 정확도를 고려하는 풀 텍스트 외에도 검색 조건의 참 / 거짓 여부만 판별해서 결과를 가져오는 것이 가능합니다.

 

풀 텍스트와 상반되는 이 특성을 정확값(Exact Value) 이라고 하는데 말 그대로 값이 정확히 일치 하는지의 여부 만을 따지는 검색입니다.

Exact Value 에는 term, range 와 같은 쿼리들이 이 부분에 속하며, 스코어를 계산하지 않기 때문에 보통 bool 쿼리의 filter 내부에서 사용하게 됩니다.

 

bool : filter (스코어 계산 X)


bool쿼리의 filter 안에 하위 쿼리를 사용하면 스코어에 영향을 주지 않습니다.

다음 3개의 검색 결과를 비교 해 보도록 하겠습니다.

 

1. 기본 match query

"fox" 가 있는 데이터를 검색합니다.

4개의 결과 값을 확인할 수 있습니다.

 

GET my_index/_search
{
  "query": {
    "match": {
      "message": "fox"
    }
  }
}

 

2. must + match 2개

fox 와 quick 이 둘다 있는 데이터를 검색합니다.

결과 값은 3개를 확인할 수 있으며, 2개의 단어에 모두 score를 책정하고 있기 때문에 이전에 찾은 결과보다 모두 점수가 높아진 것을 확인할 수 있습니다.

 

GET my_index/_search
{
  "query": {
    "bool": {
      "must": [
        {"match": {"message": "fox"}},
        {"match": {"message": "quick"}}
      ]
    }
  }
}

 

3. must, filter + match 2개

 

fox 와 quick 이 둘다 있는 데이터를 검색합니다.

fox와 quick 둘다 있는 데이터를 검색하였기 때문에 이전과 동일하게 3개의 데이터를 찾을 수 있습니다.

그러나 quick에 해당하는 단어는 점수를 책정하지 않기 때문에 점수 값은 첫번째 검색한 결과와 동일한 것을 확인할 수 있습니다.

 

GET my_index/_search
{
  "query": {
    "bool": {
      "must": [
        {"match": {"message": "fox"}}
      ],
      "filter": [
        {"match": {"message": "quick"}}
      ]
    }
  }
}

 

 

keyword (정확값 검색)


  1. 문자열 데이터는 keyword 형식으로 저장하여 정확값 검색이 가능합니다.
  2. Keyword 에 대해서는 뒤에 매핑에서 다시 설명 하겠습니다.
  3. 아래의 쿼리는 message 필드값이 "Brown fox brown dog" 문자열과 공백, 대소문자까지 정확히 일치하는 데이터만을 결과로 리턴합니다.
 
GET my_index/_search
{
  "query": {
    "bool": {
      "filter": [
        {
          "match": {
            "message.keyword": "Brown fox brown dog"
          }
        }
      ]
    }
  }
}
 
keyword 타입으로 저장된 필드는 스코어를 계산하지 않고 정확값의 일치 여부만을 따지기 때문에 스코어가 "_score" : 0.0 으로 나오게 됩니다. 스코어를 계산하지 않기 때문에 keyword 값을 검색 할 때는 filter 구문 안에 넣도록 합니다.
 
filter 안에 넣은 검색 조건들은 스코어를 계산하지 않지만 캐싱이 되기 때문에 쿼리가 더 가볍고 빠르게 실행됩니다. keyword 와 range 쿼리와 같이 스코어 계산이 필요하지 않은 쿼리들은 모두 filter 안에 넣어서 실행하는 것이 좋습니다.