곰대생/ELK Stack

Elasticsearch 검색 질의 방식

summer.west 2021. 2. 15. 14:17

 

검색 기능이 특화된 Elasticsearch의 질의 방식에는 루씬 스타일을 기반으로 하는 URI 방식과 쿼리문을 사용하는 Query DSL 방식이 있다.

 


 

URI 방식 (루씬 스타일)

 

기본 형태

GET <인덱스>/<도큐멘트>/_search?q=<필드>:<값1 값2 값3>

#curl 명령어 사용 시
curl -XGET 'http://<IP 주소>:<포트 번호>/<인덱스>/<도큐멘트>/_search?pretty&q=<필드>:<값1 값2 값3>

예시

더보기

Shakespear 데이터)

GET shakespeare/_doc/_search?q=text_entry:(Henry Prince)
GET shakespeare/_doc/_search?sort=line_id&q=text_entry:Henry

 

여러 필드 검색

GET <인덱스>/<도큐멘트>/_search?q=<필드1>:<값1>&q=<필드2>:<값2>

#curl 명령어 사용 시
curl -XGET 'http://<IP 주소>:<포트 번호>/<인덱스>/<도큐멘트>/_search?pretty&q=<필드1>:<값1>&q=<필드2>:<값2>

 

Wildcard 사용

# UserName이 s로 시작하는 데이터 검색
GET <인덱스>/<도큐멘트>/_search?q=UserName:s*

#curl 명령어 사용 시
curl -XGET 'http://<IP주소>:<포트번호>/<인덱스>/<도큐멘트>/_search?q=UserName:s*'

 

포함(must) / 미포함(must_not) 필수값 지정

# Contents에 ABC가 반드시 포함되어 있고(must), EFG는 포함되지 않은(must_not) 데이터 검색
GET <인덱스>/<도큐멘트>/_search?q=+Contents:ABC&q=-Contents:EFG

#curl 명령어 사용 시
curl -XGET 'http://<IP주소>:<포트번호>/<인덱스>/<도큐멘트>/_search?q=+Contents:ABC&q=-Contents:EFG'

 

검색 결과 정렬 기준 설정

GET <인덱스>/<도큐먼트>/_search?sort=<정렬 기준 필드>:<ASC/DESC>&q=<필드명>:<검색할 텍스트>

#curl 명령어 사용 시
curl -XGET 'http://<IP주소>:<포트번호>/<인덱스>/<도큐멘트>/_search?sort=<정렬 기준 필드>:<ASC/DESC>&q=<필드명>:<검색할 텍스트>'

 

 

Query DSL 방식 (Request Body)

 

- Filter : YES or No 기반의 검색 결과 제공 (Score 미사용), 내부적인 캐싱 기능 ➡️ 빠른 검색 속도

- Query : Score 기반의 검색 결과 제공, 캐싱 기능 X ➡️ 융통적인 검색 결과

- Filtered (Filter + Query) 는 Elasticsearch 5.0 버전부터 권장하지 않음

 

기본 형태

GET <인덱스>/<도큐멘트>/_search?
{
  "query" : {
    "<Filter 또는 Query 함수>" : {
      "<필드>" : <값>
    }
  }
}

#curl 명령어 - json 파일 사용
curl -XGET 'http://<IP주소>:<포트번호>/<인덱스>/<도큐멘트>/_search?pretty' -H 'Content-Type: application/json' -d @query.json

 

Filter 종류

더보기

✔️term : 정확히 일치하는 값만 검색 (prefix 값 제외)

GET <인덱스>/<도큐멘트>/_search?
{
  "query" : {
    "bool" : {
     "filter" : {
       "term" : {
         "<필드>" : "<검색할 텍스트>"
       } 
      } 
    }
  }
}

 

✔️terms : 멀티값 처리 ➡️ [값 1, 값2] 배열 형태로 적어주기

GET <인덱스>/<도큐멘트>/_search?
{
  "query" : {
    "bool" : {
     "filter" : {
       "terms" : {
         "<필드>" : ["<찾을 텍스트1>", "<찾을 텍스트2>"]
       } 
      } 
    }
  }
}

 

✔️range : 숫자나 날짜 데이터 범위 지정

gt (~보다 크다) / gte (크거나 같다) / lt (~보다 작다) / lte (작거나 같다)

GET <인덱스>/<도큐멘트>/_search?
{
  "query": {
    "bool": {
      "filter": {
        "range": {
          "<필드>": {
            "gte": <최소 기준값>,
            "lte": <최대 기준값>
          }
        }
      }
  }
}

 

✔️bool : must (매칭 필수, and) / must_not (매칭X 필수, or) / should (유사도 score 계산)

GET <인덱스>/<도큐멘트>/_search?
{
  "query" : {
    "bool" : {
       "must" : {
         "term" : {
           "<필드>" : "<반드시 포함할 값>" 
         }
       } 
    }
  }
}
GET <인덱스>/<도큐멘트>/_search?
{
  "query" : {
    "bool" : {
       "must_not" : {
         "term" : {
           "<필드>" : "<반드시 포함하지 않을 값>" 
         }
       } 
    }
  }
}

 

Query 종류

더보기

✔️exists : 인덱스 내부에 특정 필드가 포함되어 있는지 확인

GET <인덱스>/<도큐멘트>/_search?
{
  "query": {
    "exists": {
      "field": "<조회할 필드명>"
    }
  }
}

 

✔️match : text, number, date 필드 검색 <default> "필드":"값"

GET summer/_doc/_search?
{
  "query" : {
    "match" : {
      "<필드>" : "<찾을 값>"
    }
  }
}

멀티값 처리(세부 질의) - "operator" 추가 <default> or

숫자 데이터는 따옴표(" ") 제거 / 날짜 데이터는 "yyyy-mm-dd" 형식 사용

 

구문으로 처리 - "type":"phrase" 추가 / 구문 사이에 다른 단어 허용 갯수 설정 "slop" 옵션

"minimum_should_match" = "50%"

 

✔️match_all : 모든 도큐먼트에서 검색, 다른 쿼리문이랑 같이 쓰는 경우가 많음

GET <인덱스>/_search?
{
  "query" : {
    "match_all" : {}
  }
}

 

✔️multi_match : 다수의 필드에서 특정 값 검색

GET <인덱스>/_search?
{
  "query" : {
    "multi_match": {
      "query": "<찾을 값>",
      "fields": ["<조회할 필드1>", "<조회할 필드2>"]
    }
  }
}

 

✔️prefix : 접두어로 검색

GET <인덱스>/_search?
{
  "query" : {
    "prefix": {
      "<필드>": {
        "value": "<검색할 텍스트>"
      }
    }
  }
}

# UserName이 Su로 시작하는 데이터 검색
GET <인덱스>/_search?
{
  "query" : {
    "prefix": {
      "UserName": {
        "value": "Su"
      }
    }
  }
}

 

✔️range : 숫자나 날짜 데이터 범위 지정

gt (~보다 크다) / gte (크거나 같다) / lt (~보다 작다) / lte (작거나 같다)

GET <인덱스>/_search?
{
  "query" : {
    "range": {
      "<필드>": {
        "gte": <최소 기준값>,
        "lte": <최대 기준값>
      }
    }
  }
}

# 2020년 자료를 검색할 경우

GET <인덱스>/_search?
{
  "query" : {
    "range": {
      "date": {
        "gte": "2020-01-01",
        "lte": "2020-12-31"
      }
    }
  }
}

 

✔️fuzzy : 유사 단어 검색 지원 (예를 들어, "big" ➡️ "bag"도 검색)

* "fuzziness" : 유사도 Score의 상한/하한 범위 지정

GET <인덱스>/_search?
{
  "query" : {
    "fuzzy": {
      "<필드>": {
        "value": "<찾을 텍스트>",
        "fuzziness": <유사도 범위>
      }
    }
  }
}

 

✔️Query String : 쿼리문을 문자열 형태로

* 구문은 \" ( ) \" 형태로 표시

GET <인덱스>/<도큐멘트>/_search?
{
  "query": {
    "query_string" : {
      "query" : "<필드>: <찾을 값>"
    }
  }
}

# 구문 검색 시
GET <인덱스>/<도큐멘트>/_search?
{
  "query": {
    "query_string" : {
      "query" : "<필드>: \"<검색할 구문>\""
    }
  }
}