ElasticSearch

[엘라스틱 서치] Search your data - 검색 API (5)

고루5 2024. 5. 7. 11:19

이 시리즈에서는 엘라스틱서치 가이드(:8.13) 의 Search your data 챕터에 대해 다루고 있습니다.

https://www.elastic.co/guide/en/elasticsearch/reference/current/index.html


Filter search results

오늘은 검색결과를 필터링 하는 방법에 대해 알아보겠습니다.

1. boolean query : hits, 집계 결과 모두에 대해 필터 적용

2. post_filter 파라미터 : hits에 대한 결과물에 대해서만 필터를 적용 -> 해당 결과를 집계로 더욱 축소 가능

더보기

두 기능의 가장 큰 차이는 집계결과에 필터가 영향을 줄 수 있는가? 입니다.

bool 쿼리 : 집계 결과에 영향 O

post_filter : 집계 결과에 영향 X. only hits에만

Post filter = ~ 이후 필터링

해당 파라미터를 사용하여 검색결과를 필터링 하면 집계가 계산된 후의 hits에 대해 필터링 됩니다.  따라서 post filter는 집계 결과에 영향을 주지 않습니다.

 

예를 들어, ElasticSearch에 다음과 같이 데이터가 들어있다고 가정해 봅시다.

 

shirts/_doc/1 :

properties value
brand gucci
color red
model slim
GET /shirts/_search
{
  "query": {
    "bool": {
      "filter": [
        { "term": { "color": "red"   }},
        { "term": { "brand": "gucci" }}
      ]
    }
  }
}

 

위의 쿼리는 셔츠의 색, 브랜드에 대해 필터를 지정하고 있습니다.

일반적으로 bool 쿼리를 사용해 위와 같이 결과값을 좁힐 수 있습니다. 

 

만약 사용자가 패싯 검색(Faceted search)을 사용하고 싶은 경우에는 어떻게 찾을 수 있을까요?

Ex)  red Gucci t-shirts or dress-shirts.

 

terms aggregation 을 사용하면 됩니다.

더보기

패싯 검색 : 

수많은 정보들 사이에서 점점 범위를 좁혀가며 정보를 골라내는 방법

도서를 찾을때, 인문학, 사회과학, 예술.. 대 카테고리 > 소설, 수필, .. 중간 카테고리 > 저자의 성씨 등으로 좁혀가는 것

구찌의 레드 셔츠 모델 중 가장 인기있는 모델을 반환해라 는 다음과 같이 표현됩니다.

GET /shirts/_search
{
  "query": {
    "bool": {
      "filter": [
        { "term": { "color": "red"   }},
        { "term": { "brand": "gucci" }}
      ]
    }
  },
  "aggs": {
    "models": {
      "terms": { "field": "model" } 
    }
  }
}

 

 

이 경우 모델에 속하는 문서들을 그룹화 하고, 각 문서의 수를 센 결과를 함께 반환합니다.

 

 

이번에는 post_filter를 알아보기 위해 다음 경우를 고려해 봅시다.

 

1) 모든 색상 별로 구찌 셔츠의 수를 알고 싶다. (terms)

2) colors 검색 결과(hits)에는 "red"의 검색 결과만 보고 싶다. 

 

를 둘다 만족하는 결과물을 받고 싶다면, 다음과 같이 작성합니다.

GET /shirts/_search
{
  "query": {
    "bool": {
      "filter": {
        "term": { "brand": "gucci" } 
      }
    }
  },
  "aggs": {
    "colors": {
      "terms": { "field": "color" } 
    },
    "color_red": {
      "filter": {
        "term": { "color": "red" } 
      },
      "aggs": {
        "models": {
          "terms": { "field": "model" } 
        }
      }
    }
  },
  "post_filter": { 
    "term": { "color": "red" }
  }
}

1. 기본 쿼리는 gucci의 모든 셔츠를 반환합니다.

2. 첫번째 aggs는 구찌 셔츠의 인기 색상을 반환합니다.

3. 두번째 aggs는 하위 집합의 모델을 빨간색 구찌 셔츠로 제한합니다.

4. post_filter hits에서 빨간색을 제외한 색상을 제거합니다. 

 

Rescore filtered search results

filter를 통해 좁혀진 검색 결과에서 점수를 다시 매기는 방법은 모든 문서에 점수를 다시 매기는 것 보다 비용이 적게 들고, post_filter의 정확도를 높일 수 있습니다. 대표적으로 Query rescorer가 있습니다.

 

query rescorer는 query, post_filter단계에서 반환된 Top-K 결과에 대해서 두 번째 쿼리를 실행합니다(기본값으로 10개 검사)

원래 쿼리와 다시 채점 쿼리의 점수는 선형으로 결합되어 _score각 문서에 대한 최종 점수로 반환됩니다.

원본 쿼리와 다시 채점 쿼리의 상대적 중요성은 각각 query_weight및 를 사용하여 제어할 수 있습니다 (기본 가중치 1)

 

예시

POST /_search
{
   "query" : {
      "match" : {
         "message" : {
            "operator" : "or",
            "query" : "the quick brown"
         }
      }
   },
   "rescore" : {
      "window_size" : 50,
      "query" : {
         "rescore_query" : {
            "match_phrase" : {
               "message" : {
                  "query" : "the quick brown",
                  "slop" : 2
               }
            }
         },
         "query_weight" : 0.7,
         "rescore_query_weight" : 1.2
      }
   }
}

 

rescore의 "query"필드에는 score_mode를 추가하여 원래점수, 재채점 점수의 연산방식을 지정할 수 있습니다.

total (default) 원래 점수와 재채점 점수를 더합니다. 
multiply 원래 점수에 재채점 점수를 곱합니다.
- function query 재채점에 유용합니다.
avg 원래 점수와 재채점 점수의 평균을 구합니다.
max 원래 점수와 재채점 점수의 최대값을 취합니다.
min 원래 점수와 재채점 점수의 최소값을 가져옵니다.