Elasticsearch: 범위 쿼리 (Range Query)

Elasticsearch에서는 숫자 및 날짜 데이터를 효과적으로 검색할 수 있도록 **범위 쿼리(Range Query)**를 제공합니다.
이 쿼리는 특정 범위 안에 포함되는 데이터를 찾을 때 사용되며, 가격, 날짜, 온도, 점수 등 연속적인 값(Continuous Data)을 검색하는 데 유용합니다.

이번 글에서는 Range Query의 기본 개념, 사용법, 그리고 날짜 검색을 포함한 실전 예제까지 살펴보겠습니다.


1. Range Query란?

🔹 기본 개념

  • 특정 필드의 값이 특정 범위에 포함되는 문서만 검색할 때 사용됩니다.
  • 숫자(Number), 날짜(Date), IP 주소(IP Address) 등의 필드에서 주로 사용됩니다.
  • 점수(score)를 계산하지 않으며, 오로지 True/False 조건만으로 필터링합니다.

2. Range Query의 기본 문법

Range Query는 아래와 같은 4가지 조건을 지원합니다.

연산자 설명
gte (Greater Than or Equal) 이상 (≥) - 특정 값보다 크거나 같은 데이터 검색
gt (Greater Than) 초과 (>) - 특정 값보다 큰 데이터 검색
lte (Less Than or Equal) 이하 (≤) - 특정 값보다 작거나 같은 데이터 검색
lt (Less Than) 미만 (<) - 특정 값보다 작은 데이터 검색

📌 예제 데이터 (phones 인덱스)

POST phones/_bulk
{"index":{"_id":1}}
{"model":"Samsung GalaxyS 5","price":475,"date":"2014-02-24"}
{"index":{"_id":2}}
{"model":"Samsung GalaxyS 6","price":795,"date":"2015-03-15"}
{"index":{"_id":3}}
{"model":"Samsung GalaxyS 7","price":859,"date":"2016-02-21"}
{"index":{"_id":4}}
{"model":"Samsung GalaxyS 8","price":959,"date":"2017-03-29"}
{"index":{"_id":5}}
{"model":"Samsung GalaxyS 9","price":1059,"date":"2018-02-25"}

(📌 위 데이터는 실제 상품과 무관한 예제 데이터입니다.)


3. 숫자 검색 (Number Range Query)

📌 예제 1: 가격(price)이 700 이상, 900 미만인 스마트폰 검색

GET phones/_search
{
  "query": {
    "range": {
      "price": {
        "gte": 700,
        "lt": 900
      }
    }
  }
}

🔹 결과:

  • Samsung GalaxyS 6 (price: 795) ✅
  • Samsung GalaxyS 7 (price: 859) ✅

📌 설명:

  • gte: 700 → 700 이상
  • lt: 900 → 900 미만

4. 날짜 검색 (Date Range Query)

📌 예제 2: 2016년 1월 1일 이후 출시된 스마트폰 검색

GET phones/_search
{
  "query": {
    "range": {
      "date": {
        "gt": "2016-01-01"
      }
    }
  }
}

🔹 결과:

  • Samsung GalaxyS 7 (date: 2016-02-21) ✅
  • Samsung GalaxyS 8 (date: 2017-03-29) ✅
  • Samsung GalaxyS 9 (date: 2018-02-25) ✅

📌 설명:

  • gt: "2016-01-01" → 2016년 1월 1일보다 이후(>)인 데이터 검색

5. 날짜 포맷 변환 (Format 옵션 활용)

Elasticsearch는 기본적으로 **ISO8601 날짜 형식 (yyyy-MM-dd 또는 yyyy-MM-dd'T'HH:mm:ss)**을 사용합니다.
하지만 format 옵션을 사용하면 다른 날짜 형식도 검색할 수 있습니다.

📌 예제 3: 2016년 1월 1일 ~ 2018년 1월 1일 사이 출시된 스마트폰 검색

GET phones/_search
{
  "query": {
    "range": {
      "date": {
        "gt": "31/12/2015",
        "lt": "2018",
        "format": "dd/MM/yyyy||yyyy"
      }
    }
  }
}

🔹 결과:

  • Samsung GalaxyS 7 (date: 2016-02-21) ✅
  • Samsung GalaxyS 8 (date: 2017-03-29) ✅

📌 설명:

  • format: "dd/MM/yyyy||yyyy" → 31/12/2015 또는 2018 형식 허용

6. 현재 시간(now)과 상대적 날짜 검색

Elasticsearch에서는 now 키워드를 사용하여 현재 시간을 기준으로 상대적인 날짜를 검색할 수 있습니다.

📌 예제 4: 2016년 1월 1일 이후 + 6개월 ~ 현재(now) 기준 1년 전 사이 검색

GET phones/_search
{
  "query": {
    "range": {
      "date": {
        "gt": "2016-01-01||+6M",
        "lt": "now-365d"
      }
    }
  }
}

🔹 결과:

  • Samsung GalaxyS 8 (date: 2017-03-29) ✅
  • Samsung GalaxyS 9 (date: 2018-02-25) ✅

📌 설명:

  • "2016-01-01||+6M" → 2016년 1월 1일 이후 6개월 후
  • "now-365d" → 현재 시간(now) 기준 1년 전

7. Range Query의 특징 및 제한사항

점수(score)를 계산하지 않음

  • range 쿼리는 정확성(True/False)만 확인하고 점수를 계산하지 않습니다.
  • 검색 결과는 _score: 1.0으로 동일합니다.

점수를 조정하고 싶다면 Function Score Query 활용

  • 예를 들어, 나이가 채용 조건(24~55세)과 가까울수록 높은 점수를 부여하고 싶다면 Function Score Query를 사용해야 합니다.

📌 Function Score Query 예제 (추후 학습 필요)

GET jobs/_search
{
  "query": {
    "function_score": {
      "query": {
        "range": {
          "age": {
            "gte": 24,
            "lte": 55
          }
        }
      },
      "functions": [
        {
          "gauss": {
            "age": {
              "origin": 35,
              "scale": 10
            }
          }
        }
      ]
    }
  }
}

🔹 설명: 35세를 기준으로 점수를 조정 (추후 학습 필요)


8. 정리

개념 설명
Range Query 숫자, 날짜, IP 주소 등의 범위를 검색하는 쿼리
gte / gt 이상(≥), 초과(>)
lte / lt 이하(≤), 미만(<)
Format 옵션 날짜 포맷 변경 가능
now 키워드 현재 시간 기준 검색 가능
Function Score Query 기준점에 따라 점수를 조정하고 싶을 때 사용

9. 학습 가이드

1️⃣ Range Query의 숫자 및 날짜 검색 실습
2️⃣ Format 옵션을 사용하여 다양한 날짜 포맷 테스트
3️⃣ now, +6M, -365d 같은 상대적 날짜 검색 연습
4️⃣ Function Score Query 학습 (추후 검색 점수 조정 시 활용 가능)


다음 학습에서는 Function Score Query를 활용한 검색 결과 가중치 조정 방법을 다루겠습니다! 🚀

+ Recent posts