-
11. Query DSL 구조 및 파라미터BackEnd/elasticsearch 2021. 10. 2. 15:05반응형
엘라스틱서치로 검색 질의를 요청할 때는 Request Body 검색과 URI 검색 모두 _search API를 이용해 검색을 질의합니다. 하지만 Query DSL(JSON 구조 기반)을 이용하면 여러 개의 질의를 조합하거나 질의 결과에 대해 다시 검색을 수행하는 등 기존의 URI 검색보다 강력한 검색이 가능해집니다.
1. Query DSL 쿼리의 구조
# 요청 JSON 구조 { "size": # 리턴받는 결과의 개수 (기본값 : 10) "from": # 몇 번째 문서부터 가져올지 지정 (기본값 : 0) "timeout": # 검색을 요청해서 결과를 받는 데까지 걸리는 시간 너무 짧게 잡으면 전체 샤드에서 timeout을 넘기지 않은 문서만 결과로 출력하기에 상황에 따라 결과의 일부만 나올 수 있음 (기본값 : 무한대) "_source": {} # 검색 시 필요한 필드만 출력하고 싶을 때 사용 "query": {} # 검색 조건문이 들어가야 하는 공간 "aggs": {} # 통계 및 집계 데이터를 사용할 때 사용하는 공간 "sort": {} # 문서 결과를 어떻게 출력할지에 대한 조건을 사용하는 공간 }
# 응답 JSON 구조 { "took": # 쿼리 실행 시간 "timed_out": # 쿼리 시간이 초과할 경우를 나타냄 "_shards" : { "total": # 쿼리를 요청한 전체 샤드의 개수 "successful": # 성공적으로 응답한 샤드의 개수 "failed": # 실패한 샤드의 개수 }, "hits": { "total": # 검색어에 매칭된 문서의 전체 개수 "max_score": # 일치하는 문서의 스코어 값 중 가장 높은 값 "hits": [] # 각 문서 정보와 스코어 값 } }
2. Query DSL 쿼리와 필터
쿼리 컨텍스트 필터 컨텍스트 용도 전문 검색 시 사용 조건 검색 시 사용(예: Yes/No) 특징 분석기에 의해 분석이 수행됨.
연관성 관련 Score 계산.
루씬 레벨에서 분석 과정을 거처야 하므로 상대적으로 느림.Yes/No로 단순 판별 가능
연관성 관련 계산을 하지 않음.
엘라스틱서치 레벨에서 처리가 가능하므로 상대적으로 빠름.사용 예 "Harry Potter" 같은 문장 분석 "create_year" 필드의 값이 2018년인지 여부
"status" 필드에 'use'라는 코드 포함 여부# 쿼리 컨텍스트 POST movie_search/_search { "query": { "match": { "movieNm": "기묘한 가족" } } } # 필터 컨텍스트 POST movie_search/_search { "query": { "bool": { "must": [ { "match_all": {} } ], "filter": { "term": { "repGenreNm": "다큐멘터리" } } } } }
3. Query DSL 주요 파라미터
1) Multi Index 검색
POST movie_search,movie_auto/_search # ","를 이용해 다수의 인덱스명 입력 { ... } POST /log-2021-*/_search # 검색 요청 시 인덱스 이름을 지정할 때 "*" 와일드카드 사용 { ... }
2) 쿼리 결과 페이징
# 첫 번째 페이지 요청 POST movie_search/_search { "from": 0, "size": 5, "query": { "term": { "repNationNm": "한국" } } } # 두 번째 페이지 요청 POST movie_search/_search { "from": 5, "size": 5, "query": { "term": { "repNationNm": "한국" } } }
엘라스틱서치는 설정된 페이지를 제공하기 위해 전체를 읽어 사이즈만큼 필터링해서 제공하는 구조이기 때문에 페이지 번호가 높아질수록 쿼리 비용은 덩달아 높아질 수밖에 없다는 점에 주의해야 합니다.
3) 쿼리 결과 정렬
POST movie_search/_search { "query": { "term": { "repNationNm" : "한국" } }, "sort" :{ "prdtYear": { "order": "asc" }, "_score": { "order": "desc" } } }
4) _source 필드 필터링
# _source에 검색 결과에 포함하고 싶은 필드 지정 POST movie_search/_search { "_source": [ "movieNm" ], "query": { "term": { "repNationNm" : "한국" } } }
5) 범위 검색
# lt : < # gt : > # lte : <= # gte : >= POST movie_search/_search { "query": { "range": { "prdtYear": { "gte": "2016", "lte": "2017" } } } }
6) operator 설정
명시적으로 "and"나 "or" 연산자를 지정합니다. operator 파라미터가 생략된 경우에는 기본적으로 텀과 텀에 OR 연산을 적용합니다.
POST movie_search/_search { "query": { "match": { "movieNm": { "query": "자전차왕 엄복동", "operator": "and" # 생략 시 "자전차왕" or "엄복동" 들어있는 모든 문서 검색 } } } }
7) minimum_should_match
텀의 개수가 몇 개 이상 매칭될 때만 검색 결과로 나오게 할 경우에 사용합니다. 아래 예는 텀의 개수와 minimum_should_match 개수가 일치하기에 AND 연산과 동일한 효과를 낼 수 있습니다.
POST movie_search/_search { "query": { "match": { "movieNm": { "query": "자전차왕 엄복동", "minimum_should_match": 2 } } } }
8) fuzziness
단순히 같은 값을 찾는 Match Query를 유사한 값을 찾는 Fuzzy Query로 변경할 수 있습니다. 이는 레벤슈타인(Levenshtein) 편집 거리 알고리즘을 기반으로 문서의 필드 값을 여러 번 변경하는 방식으로 동작합니다.
예를 들어, 편집 거리의 수를 2로 설정한다면 오차범위가 두 글자 이하인 검색 결과까지 포함해서 결과로 출력합니다. 오차범위 값으로 0, 1, 2, AUTO로 총 4자기 값을 사용할 수 있는데, 이는 알파벳에는 유용하지만 한국어에는 적용하기 어렵습니다.
POST movie_search/_search { "query": { "match": { "movieNmEn": { "query": "Fli High", # "Fly High" 검색 가능 "fuzziness": 1 } } } }
9) boost
관련성이 높은 필드나 키워드에 가중치를 더 줄 수 있게 해줍니다. 아래 예는 한글 영화 제목이 일치하면 한글 영화 제목에서 계산되는 스코어에 가중치 값으로 3을 곱합니다.
POST movie_search/_search { "query" : { "multi_match": { "query": "Fly", "fields": ["movieNm^3","movieNmEn"] } } }
반응형'BackEnd > elasticsearch' 카테고리의 다른 글
13. 집계(Aggregation) (0) 2021.10.06 12. Query DSL의 주요 쿼리 (0) 2021.10.02 10. 검색 API (0) 2021.09.25 09. 문서관리 API(Document API) (0) 2021.09.24 08. 엘라스틱서치 분석기 (0) 2021.09.24