본문 바로가기

카테고리 없음

[ES] 엘라스틱서치 QueryDSL 사용한 대표 쿼리 실습

 

 

1. 대표적인 Full Text query 

 

1) match_all

별다른 조건 없이 해당 인덱스의 모든 도큐먼트를 검색하는 쿼리

검색 시 쿼리를 넣지 않으면 자동으로 match_all이 적용됨 

 

 

 

2) match

풀 텍스트 검색에 사용되는 가장 일반적인 쿼리

여러개의 검색도 가능(디폴트로 OR 조건으로 검색됨)

 

GET 인덱스명/_search
{
  "query": {
    "match": {
      "필드명": "fruit"
    }
  }
}

 

기본으로 OR 조건이 적용됨

GET 인덱스명/_search
{
  "query": {
    "match": {
      "필드명": "fruit animal"
    }
  }
}

 

 

AND 조건으로 검색하기

GET 인덱스명/_search
{
  "query": {
    "match": {
      "필드명": {
        "query":"fruit animal",
        "operator":"and"
      }
    }
  }
}

 

3) match_pharase

공백을 포함하며, 검색어 순서까지 고려하여 정확히 일치하는 내용 검색

GET 인덱스명/_search
{
  "query": {
    "match_phrase": {
      "필드명": "fruit animal"
    }
  }
}

 

match_pharase 의 _slop 옵션

지정된 값 만큼 단어 사이에 다른 검색어가 있는 것을 허용하는 slop 옵션

slop을 이용하여 정확도를 조절해나가며 원하는 검색 결과의 범위를 넓힐 수 있음

slop을 너무 크게 잡을 시 검색 범위가 넓어져 관련 없는 결과가 나오는 확률이 높아질 수 있으므로 1 이상의 수는 사용하지 않는 것을 권장

 

GET 인덱스명/_search
{
  "query": {
    "match_phrase": {
      "필드명": "fruit natural"
    }
  }
}

 

slop 옵션 주기

GET 인덱스명/_search
{
  "query": {
    "match_phrase": {
      "필드명": {
        "query": "fruit natural",
        "slop": 1
      }
    }
  }
}

 

 

4) query_string

URL 검색에 사용하는 루씬의 검색 문법을 본문 검색에 이용할 때 사용

 

GET 인덱스명/_search
{
  "query": {
    "query_string": {
      "default_field": "필드명",
      "query": "(fruit OR animal) OR \"lemontea cafe\""
    }
  }
}

 

 

2. 복합 쿼리- Bool Query

  • 복합 쿼리의 종류에는 bool, boosting, constant_score, function_score 쿼리가 있음(실습은 bool 쿼리만 진행)
  • 본문 검색에서 여러 쿼리를 조합하기 위해서는 상위에 bool 쿼리를 사용하고 그 안에 다른 쿼리들을 넣어서 사용
  • bool 쿼리는 4개의 인자(must, must_not, should, filter)를 가지고 있으며 그 인자 안에 다른 쿼리들을 넣는 방식으로 동작함
  • bool 쿼리의 must, should 등은 표준 SQL의 AND, OR 등과 유사하지만 정확히 같지는 않음

 

1) must

쿼리가 참인 도큐먼트 검색

# 필드명에 fruit 포함되어 있고 and animal natural 문구가 포함되어 있는 도큐먼트 검색

GET 인덱스명/_search
{
  "query": {
    "bool": {
      "must": [
        {
          "match": {
            "필드명": "fruit"
          }
        },
        {
          "match_phrase": {
            "필드명": "animal natural"
          }
        }
      ]
    }
  }
}

 

2) must_not

쿼리가 거짓인 도큐먼트 검색

GET 인덱스명/_search
{
  "query": {
    "bool": {
      "must": [
        {
          "match": {
            "필드명": "fruit"
          }
        }
      ],
      "must_not": [
        {
          "match_phrase": {
            "필드명": "natural"
          }
        }
      ]
    }
  }
}

 

3) should

검색 결과 중 이 쿼리에 해당하는 도큐먼트의 점수를 조정

match 쿼리와 조합 예시: fox 검색 결과 중 lazy를 포함한 결과에 가중치 부여

# 필드명의 값에 fruit이 들어간 도큐먼트 조회

GET 인덱스명/_search
{
  "query": {
    "match": {
      "필드명": "fruit"
    }
  }
}

 

apple이 포함된 도큐먼트에 가중치를 두어 위에서 조회했던 것과 다른 결과를 확인해 볼 수 있음

GET 인덱스명/_search
{
  "query": {
    "bool": {
      "must": [
        {
          "match": {
            "필드명": "fruit"
          }
        }
      ],
      "should": [
        {
          "match": {
            "필드명": "apple"
          }
        }
      ]
    }
  }
}

 

 

 

4) filter

  • 쿼리가 참인 도큐먼트를 검색하지만 스코어 계산하지 않음
  • must 보다 검색 속도가 빠르고 캐싱이 가능함
# apple이 포함된 도큐먼트를 찾아야함 -> 참인 도큐먼트를 찾지만 가중치를 주지는 않음
# 위 테스트와 비교해보면 should로 apple에 가중치 줬을 때와
# filter로 가중치를 주지 않을 때 _score가 다른 것을 확인할 수 있음  

GET 인덱스명/_search
{
  "query": {
    "bool": {
      "must": [
        {
          "match": {
            "필드명": "fruit"
          }
        }
      ],
      "filter": [
        {
          "match": {
            "필드명":"apple"
          }
        }
      ]
    }
  }
}

 

 

 

3. 범위 쿼리(Range Query)

  • 숫자나 날짜 형식의 저장/조회가 가능함
  • range 쿼리를 이용해서 검색
  • range 정확도를 계산하지 않고 오로지 범위에 해당 되는지 true/false만을 판단
  • 경우에 따라 range 쿼리에 기준점을 주고 스코어를 적용해야할 필요가 있다면 function_score 쿼리 참고

 

1) range 쿼리의 파라미터

  • gte(Greater-than or equal to):  이상(같거나 큼)
  • gt(Greater-than): 초과(큼)
  • lte(Less-than or equal to): 이하(같거나 작음)
  • lt(Less-than): 미만(작음)

 

2) 입력 형식

range : {<필드명>: {<파라미터>:<값>}}

 

 

3) 숫자 범위 조회

# 데이터 입력
POST cars/_bulk
{"index":{"_id":1}}
{"model":"car1","price":4500,"date":"2024-02-21"}
{"index":{"_id":2}}
{"model":"car2","price":2000,"date":"2013-12-13"}
{"index":{"_id":3}}
{"model":"car3","price":5000,"date":"2022-02-02"}
{"index":{"_id":4}}
{"model":"car4","price":3000,"date":"2019-05-01"}
{"index":{"_id":5}}
{"model":"car5","price":1000,"date":"2015-06-25"}
{"index":{"_id":6}}
{"model":"car6","price":5500,"date":"2023-07-13"}

 

# pricerk 3000이상 4500이하인 도큐먼트 조회

GET cars/_search
{
  "query": {
    "range": {
      "price": {
        "gte": 3000,
        "lte": 4500
      }
    }
  }
}

 

4) 날짜 범위 조회

GET cars/_search
{
  "query": {
    "range": {
      "date": {
        "gt": "2022",
        "lt": "2023"
      }
    }
  }
}

 

 

 

위에서 실습한 쿼리 외에도 Elasticsearch에서 제공해주는 다양한 DSL Query가 있으니 공식문서를 확인해서 필요한 쿼리 사용하기

 

https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl.html

 

Query DSL | Elasticsearch Guide [8.12] | Elastic

Elasticsearch provides a full Query DSL (Domain Specific Language) based on JSON to define queries. Think of the Query DSL as an AST (Abstract Syntax Tree) of queries, consisting of two types of clauses: Leaf query clauses Leaf query clauses look for a par

www.elastic.co