-
10. 검색 APIBackEnd/elasticsearch 2021. 9. 25. 07:33반응형
엘라스틱서치는 색인 시점에 Analyzer를 통해 분석된 텀(Term)을 Term, 출현빈도, 문서번호와 같이 역색인 구조로 만들어 내부적으로 저장합니다. 검색 시점에는 Keyword 타입과 같은 분석이 불가능한 데이터와 Text 타입과 같은 분석이 가능한 데이터를 구분해서 분석이 가능할 경우 분석기를 이용해 분석을 수행합니다. 이를 통해 검색 시점에도 텀을 얻을 수 있으며, 해당 텀으로 역색인 구조를 이용해 문서를 찾고 이를 통해 스코어를 계산해서 결과로 제공합니다.
엘라스틱서치에서 제공하는 검색 API는 기본적으로 질의(Query)를 기반으로 동작합니다. 검색 질의에는 루씬에서 사용하던 전통적인 방식의 URI 검색과 RESTful API를 이용한 Request Body 검색이 존재합니다.
1. 실습 환경 준비(스냅샷 생성 및 복구)
Window10 실습환경으로 Linux 명령어를 사용하기 위해 PowerShell을 설치하고 다음 명령어를 입력하면 search_example 데이터가 javacafe라는 이름의 논리적인 스냅샷으로 생성됩니다. (02. 엘라스틱서치 설치 참고)
PS C:\Windows\System32> curl -XPUT "http://localhost:9200/_snapshot/javacafe" -H "Content-Type: application/json" -d ' { >> \"type\": \"fs\", >> \"settings\": { >> \"location\": \"C:\\elasticsearch\\snapshot\\book_backup\\search_example\", >> \"compress\": true >> } >> }' {"acknowledged":true}
> Window의 경우, 데이터(-d) 내부 double-quote(") 앞에 백슬러시(\)를 추가로 붙여주어야 합니다.
movie_search 스냅숏을 복구합니다.
PS C:\Windows\System32> curl -XPOST 'http://localhost:9200/_snapshot/javacafe/movie-search/_restore' {"accepted":true}
kibana에서 movie_search 인덱스가 생성되었는지 확인할 수 있습니다.
GET /_cat/indices/movie_search?v&pretty
2. URI 검색
URI 검색은 파라미터를 전달하는 표현법으로 웹브라우저를 이용해 빠르게 테스트할 수 있습니다. Request Body 검색에 비해 단순하고 사용하기 편리하지만 복잡한 질의문을 입력하기 힘들다는 단점이 있습니다. 또한 엘라스틱서치에서 제공하는 모든 검색 옵션을 사용할 수 없습니다.
파라미터 기본값 설명 q - 검색을 수행할 쿼리 문자열 조건을 지정한다. df - 쿼리에 검색을 수행할 필드가 지정되지 않았을 경우 기본값으로 검색할 필드를 지정한다. analyzer 검색 대상 필드에 설정된 형태소 분석기 쿼리 문자열을 형태소 분석할 때 사용할 형태소 분석기를 지정한다. analyze_wildcard false 접두어/와일드카드(*) 검색 활성화 여부를 지정한다. default_operator OR 두 개 이상의 검색 조건이 쿼리 문자열에 포함된 경우 검색 조건 연산자를 설정한다. _source true 검색 결과에 문서 본문 포함 여부를 지정한다. sort - 검색 결과의 정렬 기준 필드를 지정한다. from - 검색을 시작할 문서의 위치를 설정한다. size - 반환할 검색 결과 개수를 설정한다. URI 검색에 q옵션에 사용되는 검색 문자열은 Request Body 검색에서 제공하는 Query String Search 옵션과 동일하게 동작합니다. 아래는 다양한 필드를 검색 조건으로 추가해서 검색을 요청한 예제입니다.
POST movie_search/_search?q=movieNmEn:* AND prdtYear:2017&analyze_wildcard=true&from=0& size=5&sort=_score:desc,movieCd:asc&_source_includes=movieCd,movieNm,movieNmEn,typeNm
3. Request Body 검색
HTTP 요청 시 본문에 JSON 형태로 검색 조건을 기록해서 검색을 요청합니다. Query DSL(Domain-specific language) 문법을 사용합니다.
POST movie_search/_search { "query": { "query_string": { "default_field": "movieNmEn", "query": "Family" } } }
POST movie_search/_search { "query": { "query_string": { "default_field": "movieNmEn", "query": "movieNmEn:* OR prdtYear:2017" } }, "from": 0, "size": 5, "sort": [ { "_score": { "order": "desc" }, "movieCd": { "order": "asc" } } ], "_source": [ "movieCd", "movieNm", "prdtYear" ] }
4. 효율적인 검색을 위한 환경설정
1) 동적 분배 방식의 샤드 선택
엘라스틱서치는 검색을 수행할 때 동일 데이터를 가지고 있는 샤드 중 하나만 선택해 검색을 수행합니다. 기본적으로 라운드로빈(Round Robin) 방식의 알고리즘을 사용합니다. 동적 분배 방식은 검색 요청의 응답시간, 검색 요청을 수행하는 스레드 풀(Thread Pool)의 크기 등을 고려해 최적의 샤드를 동적으로 결정하는 방식입니다.
# 요청 PUT _cluster/settings { "transient": { "cluster.routing.use_adaptive_replica_selection": true } } # 결과 { "acknowledged" : true, "persistent" : { }, "transient" : { "cluster" : { "routing" : { "use_adaptive_replica_selection" : "true" } } } }
2) 글로벌 타임아웃 설정
개별 검색 요청 시 Request Body에 직접 타임아웃을 설정할 수 있지만 모든 검색 쿼리에 동일하게 적용되도록 정책으로 설정하는 것이 좋습니다. 글로벌로 적용되는 타임아웃의 기본 정책은 무제한(-1)입니다.
# 요청 PUT _cluster/settings { "transient": { "search.default_search_timeout": "1s" } } # 결과 { "acknowledged": true, "persistent": {}, "transient": { "search": { "default_search_timeout": "1s" } } }
5. 부가적인 검색 API
1) Search Shards API
검색이 수행되는 노드 및 샤드에 대한 정보를 확인할 수 있습니다. 질의를 최적화하거나 질의가 정상적으로 수행되지 않을 때 문제를 해결하는 데 유용하게 활용할 수 있습니다.
POST movie_search/_search_shards
2) Multi Search API
여러 건의 검색 요청을 통합해서 한번에 요청하고 한번에 결과를 종합해서 받을 때 사용하는 API입니다. Multi Search API를 사용하면 동시에 여러 개의 색인에서 검색을 수행할 수 있으므로 사용자별 맞춤 페이지 등을 구현할 때 여러 인덱스에서 사용자별로 특화된 정보를 가져오거나 할 때 유용하게 활용할 수 있습니다.
POST _msearch {"index" : "movie_auto"} {"query" : {"match_all" : {}}, "from" : 0, "size": 10} {"index" : "movie_search"} {"query" : {"match_all" : {}}, "from" : 0, "size" : 10}
3) Count API
검색된 문서의 개수만 가져올 때 사용합니다.
# URI 방식 POST movie_search/_count?q=prdtYear:2017 {} # Request Body 방식 POST movie_search/_count { "query": { "query_string": { "default_field": "prdtYear", "query": "2017" } } }
4) Validate API
쿼리가 유효하게 작성됐는지 검증하는 것이 가능합니다.
# URI 방식 POST movie_search/_validate/query?q=prdtYear:2017 {} # Request Body 방식 POST movie_search/_validate/query # POST movie_search/_validate/query?rewrite=true #rewrite=true : 실패 정보 확인 { "query" : { "match": { "prdtYear": 2017 } } } # 결과 { "_shards" : { "total" : 1, "successful" : 1, "failed" : 0 }, "valid" : true # 실패 시 false }
5) Explain API
특정 문서에 대해 요청한 쿼리가 어떻게 스코어가 계산되는지 자세하게 확인할 수 있습니다. 이러한 정보를 이용하면 특정 문서가 잘 검색되지 않을 때 디버깅 정보로 유용하게 활용할 수 있습니다.
# ID가 "8"인 문서에 대해 스코어 값이 어떤 방식으로 계산됐는지 확인 POST movie_search/_doc/8/_explain { "query": { "term": { "prdtYear": 2017 } } }
6) Profile API
쿼리에 대한 상세한 수행 계획과 각 수행 계획별 수행된 시간을 돌려주므로 성능을 튜닝하거나 디버깅할 때 유용하게 활용할 수 있습니다. 다만 결과가 매우 방대합니다. "내 질의 결과에 대한 스코어가 어떻게 계산됐는가?"를 확인할 때는 Explain API를 사용하고, "내 질의를 실행하는 과정에서 각 샤드별로 얼마나 많은 시간이 소요됐는가?"를 알고 싶을 때는 Profile API를 사용합니다.
POST movie_search/_search { "profile": true, "query": { "match_all": {} } }
반응형'BackEnd > elasticsearch' 카테고리의 다른 글
12. Query DSL의 주요 쿼리 (0) 2021.10.02 11. Query DSL 구조 및 파라미터 (0) 2021.10.02 09. 문서관리 API(Document API) (0) 2021.09.24 08. 엘라스틱서치 분석기 (0) 2021.09.24 07. 데이터 타입(Data Type) (0) 2021.09.20