[Elastic Search] 엘라스틱 서치 Query & Filter

Baedonguri·2023년 2월 10일
2
post-thumbnail

Elastic Search에서 원하는 결과를 도출하는 방법은 크게 두가지가 존재한다.

  • 쿼리 (Query)를 이용하는 방법.
  • 필터 (Filter)를 이용하는 방법.

쿼리와 필터의 주요 차이점은 다음과 같다.

  1. 검색 결과로 반환되는 문서의 관련성 점수에 영향을 미치는가?
  2. 캐싱이 되는가?
  1. 쿼리는 검색 쿼리와 관련된 각 문서의 관련성 점수를 결정하는 데 사용되며, 캐싱이 되지 않는다.
    관련성 점수는 문서의 순위를 매기는 데 사용되며, 가장 관련성이 높은 문서가 검색 결과에 먼저 나타난다.
    예를 들어, 특정 필드에 대한 일치 질의는 해당 필드에서 검색되는 정확한 텍스트를 포함하는 문서에 더 높은 관련성 점수를 할당하게 된다.
  2. 필터는 검색 결과를 특정 기준과 일치하는 문서로만 제한하는 데 사용된다.
    필터는 문서의 관련성 점수에 영향을 미치지 않지만 반환되는 문서 수를 좁힌다.
    예를 들어, 날짜 필드의 범위 필터는 지정된 범위 내의 날짜를 가진 문서만 반환하게 된다.
    더불어, term, terms, prefix, range 필터들은 기본적으로 캐싱이 되며, 메모리와 속도면에서
    우위를 가져갈 수 있음.

즉, 쿼리는 관련성 점수를 결정하는 데 사용되고 필터는 결과를 제한하는 데 사용되며,
score가 필요한 경우엔 쿼리를 이용하고, 그렇지 않다면 필터를 사용하면 된다.


Relevance Score

  • 관련성 점수는 양의 부동 소수점 숫자로,_score API의 메타데이터 필드인데, 점수가 높은 곳일수록
    관련성이 높은 문서이다.
  • 기본적으로 Elastic Search는 각 문서가 조회에 얼마나 적합한지 측정하는 관련 점수별로 일치하는 검색 결과를 정렬함.
  • 쿼리 유형에 따라 관련 점수를 다르게 계산할 수 있지만 점수 계산은 쿼리 구가 쿼리 컨텍스트에서 실행되는지 또는 필터 컨텍스트에서 실행되는지 여부에 따라 달라지게 된다.

자주 사용되는 쿼리에 대한 예제를 살펴보도록 하자.

  1. Match : 특정 필드뿐만 아니라 전체 문서에서 일치하는 항목을 찾는 전체 텍스트 검색 쿼리

    POST index_name/_search
    {
      "query": {
        "match": {
          "field_name": "value to search"
        }
      }
    }

  1. Term : 특정 필드 또는 특정 문자열의 값과 같은 정확한 값과 일치하는 쿼리

    POST index_name/_search
    {
      "query": {
        "term": {
          "field_name": "value to search"
        }
      }
    }

    위 예시에서 term 쿼리는 필드값이 정확히 ‘field_name’ 인 문서를 찾으며, 대소문자를 구분하며 일부 값과 일치하지 않음.
    부분 값을 검색하려는 경우에는 wildcard 쿼리 또는 fuzzy 쿼리를 사용할 수 있음

    POST index_name/_search
    {
      "query": {
        "terms": {
          "field_name": ["value1", "value2", "value3"]
        }
      }
    }

    여러 값을 검색할 수도 있음.
    ‘field_name’ 필드의 값이 정확히 ‘value1’, ‘value2’, ‘value3’ 인 문서와 일치함


  1. Bool : 여러 쿼리를 부울 논리(예: AND, OR, NOT)로 결합할 수 있는 쿼리

    POST index_name/_search
    {
      "query": {
        "bool": {
          "must": [
            {
              "term": {
                "field1": "value1"
              }
            },
            {
              "term": {
                "field2": "value2"
              }
            }
          ],
          "must_not": [
            {
              "term": {
                "field3": "value3"
              }
            }
          ],
          "should": [
            {
              "term": {
                "field4": "value4"
              }
            },
            {
              "term": {
                "field5": "value5"
              }
            }
          ],
          "minimum_should_match": 1
        }
      }
    }
    1. must 절은 term 쿼리가 모두 일치해야 함을 지정함. (field1와 value1 및 field2와 value2 둘다 매치 )
    2. must_not 절은 문서가 term 쿼리와 일치하지 않아야 함을 지정함. (field3가 value3와 매치되지 않아야함)
    3. should 절은 문서가 적어도 하나의 term 쿼리와 일치해야 함을 지정함. (field4와 value4 매치 또는 field5와 value5 매치)
      또한, minimum_should_match를 통해 일치해야하는 최소 수를 지정할 수 있음

  1. Range : 지정된 범위 내의 필드 값과 문서를 일치시키는 쿼리

    POST index_name/_search
    {
      "query": {
        "range": {
          "field_name": {
            "gte": "lower_bound",
            "lte": "upper_bound"
          }
        }
      }
    }
    • 위 예제에서 range 쿼리는 field_name 필드의 값이 lower_bound보다 크거나 같고
      upper_bound보다 작거나 같은 문서와 일치함.
      아래와 같은 다른 범위 쿼리 연산자를 사용할 수도 있음
      - gt (보다 큼),
      - lt (보다 작음)
      - gte (보다 크거나 같음)
      - lte (보다 작거나 같음)
    POST index_name/_search
    {
      "query": {
        "range": {
          "field_name": {
            "gt": "lower_bound"
          }
        }
      }
    }
    • field_name 필드의 값이 lower_bound보다 큰 문서와 일치하는 range 쿼리의 예시
    POST index_name/_search
    {
      "query": {
        "bool": {
          "must": [
            {
              "range": {
                "field1": {
                  "gte": "lower_bound1",
                  "lte": "upper_bound1"
                }
              }
            },
            {
              "range": {
                "field2": {
                  "gte": "lower_bound2",
                  "lte": "upper_bound2"
                }
              }
            }
          ]
        }
      }
    }
    • 단일 검색 요청에서 여러 range 쿼리를 bool 쿼리와 결합하여 사용하는 쿼리의 예시.
    • 위 예시에서 bool 쿼리에는 두 개의 range 쿼리가 있는 must 절이 있는데,
      검색 요청은 두 범위 쿼리와 일치하는 문서만 반환하게 됨.

  1. Aggregation : 하나 이상의 필드를 기반으로 검색 결과를 그룹화하고 요약하는 쿼리

    POST index_name/_search
    {
      "size": 0, 
      "aggs": {
        "group_by_field1": {
          "terms": {
            "field": "field1"
          },
          "aggs": {
            "average_field2": {
              "avg": {
                "field": "field2"
              }
            },
            "sum_field3": {
              "sum": {
                "field": "field3"
              }
            }
          }
        }
      }
    }

    위 예시에서는 검색 요청의 aggs 섹션은 두 개의 집계를 지정하는데,
    첫 번째 집계인 group_by_field1field1 필드의 값을 기준으로 문서를 그룹화하기 위해 용어 집계를 사용.

    두 번째 수준의 집계인 average_field2sum_field3avgsum aggregation을 사용하여 각 문서 그룹에 대해 각각 field2field3 필드에 있는 값의 평균과 합계를 계산.

    size 매개변수가 0으로 설정되어 있으므로, 검색 요청은 실제 문서를 반환하지 않고 집계된 결과만 반환함.

    단일 검색 요청에서 여러 aggregation을 사용하여 보다 복잡한 데이터 분석 및 그룹화를 수행할 수 있음.


  • Elastic search에서 필터는 특정 조건을 기준으로 검색 결과를 필터링하는 데 사용된다.
    특정 기준을 충족하는 문서의 하위 집합으로 쿼리 결과를 제한하는 데 사용되며, 쿼리와 달리 필터는 문서의 관련성 점수에 영향을 주지 않는다.
  • 필터는 cache되며, 재사용될 수 있기 때문에 일반적으로 쿼리보다 빠르며, 각 검색 요청에 대해 쿼리를 다시 실행해야 한다.
  • 또한 필터는 검색 결과를 더 작은 집합으로 빠르게 좁힐 수 있기 때문에 많은 문서를 처리해야 할 때 성능 최적화에도 사용된다.
  • 필터를 쿼리와 함께 사용하여 검색 결과에 포함되는 문서를 제어할 수 있다.
    예를 들어 필터를 사용하여 검색 결과를 특정 날짜 범위로 제한하거나 특정 필드 값과 일치시킬 수 있음.

Elastic Search에는 term Filter, range Filter 및 bool Filter를 포함한 여러 유형의 필터가 존재하는데,
필터 선택은 검색의 특정 요구 사항과 검색 중인 데이터에 따라 달라지게 된다.


  • Term Filter: 필드의 정확한 값을 일치시키는 데 사용한다. 예를 들어, 필드에서 특정 값을 가진 문서를 검색하는 데 사용.
  • Range Filter: 특정 범위 내의 값을 일치시키는 데 사용한다. 예를 들어, 특정 범위 내의 날짜 필드가 있는 문서를 검색하는 데 사용.
  • Exists Filter: 특정 필드에 null이 아닌 값을 가진 문서를 일치시키는 데 사용됨.
  • Missing Filter: 특정 필드에 null 값이 있는 문서를 일치시키는 데 사용됨.
  • Prefix Filter: 필드에 특정 접두사가 있는 문서를 일치시키는 데 사용됨.
  • Wildcard Filter: 필드에 특정 패턴이 있는 문서를 일치시키는 데 사용됨.
  • Regexp Filter: 필드의 정규식 패턴과 일치하는 문서를 일치시키는 데 사용됨.
  • Nested Filter: 문서의 중첩된 오브젝트 내에서 검색하는 데 사용됨.
  • Ids Filter: 고유한 ID를 기준으로 문서를 일치시키는 데 사용됨.
  • Type Filter: 문서 유형에 따라 문서를 일치시키는 데 사용됨.
profile
Software Engineer

2개의 댓글

comment-user-thumbnail
2023년 2월 10일

브라보! 멋지다 배동준~

1개의 답글