Elasticsearch 검색 질의 방식
검색 기능이 특화된 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" : "<필드>: \"<검색할 구문>\""
}
}
}