본문 바로가기
엘라스틱서치

5. 검색과 쿼리

by N.Damgom 2021. 9. 5.

5. 검색과 쿼리 - Query DSL

  • 검색: 수많은 대상 데이터 중에서 조건에 부합하는 데이터로 범위를 축소하는 행위
  • 엘라스틱서치 Query DSL은 JSON 형식이다.

1) 풀텍스트 쿼리

  • match_all:
    • 조건없이 해당 인덱스의 모든 도큐먼트를 검색한다.
    • 쿼리 없이 실행하는 것과 같은 결과를 되돌려준다. 
GET my_index/_search
{
  "query":{
    "match_all":{ }
  }
}

 

  • match
    • 검색에 사용되는 일반적인 쿼리
    • 기본적으로 띄어쓰기는 OR 조건으로 검색되나, operator 옵션으로 변경할 수 있다.
GET my_index/_search
{
  "query": {
    "match": {
      "message": "quick dog" # field: value 형태
    }
  }
}

GET my_index/_search
{
  "query": {
    "match": {
      "message": {
        "query": "quick dog", # query와 operator로 나뉜다.
        "operator": "and"
      }
    }
  }
}

 

  • match_phrase
    • 공백을 구분자로 생각하지 않고 그대로 쿼리한다.
    • slop으로 공백으로 나뉜 단어 사이에 몇 개의 단어가 끼어들 수 있을지 지정할 수 있다.
    • slop은 1까지만 권장된다.
GET my_index/_search
{
  "query": {
    "match_phrase": {
      "message": "lazy dog"
    }
  }
}
GET my_index/_search
{
  "query": {
    "match_phrase": {
      "message": {
        "query": "lazy dog",
        "slop": 1
      }
    }
  }
}

 

  • query_string
    • 루씬 검색 문법을 사용할 때 쓴다.
GET my_index/_search
{
  "query": {
    "query_string": {
      "default_field": "message",
      "query": "(jumping AND lazy) OR \"quick dog\""
    }
  }
}

 

2) Bool 복합 쿼리

  • 여러 쿼리를 조합하기 위해서는 상위에 bool 쿼리를 사용하고 그 안에 인자가 있으며 인자 안에 다른 쿼리를 배열로 넣는다.
  • 4개의 인자가 있다.
    • must: 쿼리가 참인 도큐먼트를 검색한다.
    • must_not: 쿼리가 거짓인 도큐먼트를 검색한다.
    • should: 검색 결과 중 이 쿼리에 해당하는 도큐먼트의 점수를 높인다.
    • filter: 쿼리가 참인 도큐먼트를 검색하지만 스코어를 계산하지 않으므로 must 보다 빠르고 캐싱이 가능하다.
GET <인덱스명>/_search
{
  "query": {
    "bool": {
      "must": [
        { <쿼리> }, … # 인자 안에 여러개의 쿼리가 들어갈 수 있다.
      ],
      "must_not": [
        { <쿼리> }, …
      ],
      "should": [
        { <쿼리> }, …
      ],
      "filter": [
        { <쿼리> }, …
      ]
    }
  }
}

GET my_index/_search
{
  "query": {
    "bool": {
      "must": [## 인자 안에 쿼리가 배열로 들어간다.
        {
          "match": {
            "message": "quick"
          }
        },
        {
          "match_phrase": {
            "message": "lazy dog"
          }
        }
      ]
    }
  }
}

 

3. 정확도

  • 검색 결과가 검색 조건과 얼마나 일치하는지를 relavancy라고 표현한다.
  • TF-IDF 기반의 알고리즘을 사용한다.(BM25)

4. Bool: Should

  • should 쿼리는 match_phrase와 함께 유용하게 쓰일 수 있다.
  • 예를들어 전문이 그대로 들어있는 경우 score를 높인다.
GET my_index/_search
{
  "query": {
    "bool": {
      "must": [
        {
          "match": {
            "message": {
              "query": "lazy dog" # lazy or dog가 들어있는 검색 결과를 가져온다.
            }
          }
        }
      ],
      "should": [
        {
          "match_phrase": {
            "message": "lazy dog" # 딱 "lazy dog"로 되어있는 경우 점수를 높인다.
          }
        }
      ]
    }
  }
}

 

5. 정확값 쿼리 - Exact Value Query

  • 정확도 쿼리는 정확히 일치하는 검색 결과만 가져온다.
  • 검색 조건의 참 / 거짓 여부만 판별한다.
  • term, range 쿼리가 Exact Value에 해당한다.
  • bool 쿼리 내 filter 안에 하위 쿼리를 작성하면 스코어에 영향을 주지 않는다.
GET my_index/_search
{
  "query": {
    "bool": {
      "must": [
        {
          "match": {
            "message": "fox"
          }
        }
      ],
      "filter": [ #스코어 영향을 주지 않는다.(fox만 검색했을 때랑 같은 스코어가 나온다.)
        {
          "bool": {
            "must_not": [ #filter 내부에서 must_not 쿼리를 쓸려면 bool로 감싸야 한다.
              {
                "match": {
                  "message": "dog"
                }
              }
            ]
          }
        }
      ]
    }
  }
}

 

  • 문자열 데이터는 keyword 형식으로 저장해서 정확값 검색이 가능하다.
  • keyword는 스코어를 계산하기 않기 때문에 filter 안에 넣어야 한다.

5.6 범위 쿼리 - Range Query

  • 숫자, 날짜 형식은 range 쿼리를 이용해서 검색한다.
  • range쿼리는 range : { <필드명>: {<파라미터>:<값> } } 형식으로 입력된다.
  • 해당 필드에 대해 어떤 범위로(파라미터로 지정) 검색할 지 지정한다.
  • 두 개의 파라미터를 이용해서 닫힌 범위를 만들 수 있다.
  • 파라미터는 다음과 같이 4 종류가 있다.
    • gte: Greater than or eqaul to
    • gt: Greater than
    • lte: Less than or equal to
    • lt: Less than
GET phones/_search
{
  "query": {
    "range": {
      "price": {
        "gte": 700,
        "lt": 900
      }
    }
  }
}

 

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

 

  • 기본적으로 ISO8601 (2016-01-01 또는 2016-01-01T10:15:30) 포맷을 사용하나,
  • format 파라미터로 커스텀하게 만들 수 있다.
GET phones/_search
{
  "query": {
    "range": {
      "date": {
        "gt": "31/12/2015",
        "lt": "2018",
        "format": "dd/MM/yyyy||yyyy"
      }
    }
  }
}

 

  • 날짜른 검색할때는 예약어 now와 y,M,d,h,m,s를 사용할 수 있다.
GET phones/_search
{
  "query": {
    "range": {
      "date": {
        "gt": "2016-01-01||+6M",
        "lt": "now-365d"
      }
    }
  }
}

 

  • range 쿼리는 score를 계산하지 않는다.
  • score를 계산할려면 function_score를 사용해야한다.

출처: https://esbook.kimjmin.net

'엘라스틱서치' 카테고리의 다른 글

7. 인덱스 설정과 매핑  (0) 2021.09.06
6. 데이터 색인과 텍스트 분석  (0) 2021.09.06
4. 데이터 처리  (0) 2021.08.31
3. 시스템 구조  (0) 2021.08.31
2. 시작하기  (0) 2021.08.31