목차
1. JavaRestClient 기반 문서 쿼리
1.1 쿼리 API 시연
1.1.1 기본 쿼리 프레임워크
다음으로 match_all을 통해 모두 쿼리하여 다음 기본 API를 보여줍니다.
@Test
public void testMatchAll() throws IOException {
//1.准备 SearchRequest
SearchRequest request = new SearchRequest("hotel");
//2.准备参数
request.source().query(QueryBuilders.matchAllQuery());
//3.发送请求,并接收响应
SearchResponse response = client.search(request, RequestOptions.DEFAULT);
//4.解析响应
handlerResponse(response);
}
/**
* 处理响应
* @param response
*/
private void handlerResponse(SearchResponse response) {
//1.解析结果
SearchHits hits = response.getHits();
//获取总条数
long total = hits.getTotalHits().value;
SearchHit[] hits1 = hits.getHits();
for(SearchHit searchHit : hits1) {
//获取source
String json = searchHit.getSourceAsString();
System.out.println(json);
}
}
위에서 볼 수 있듯이 쿼리의 기본 단계는 다음과 같습니다.
- SeaechRequest 객체를 생성하고 인덱스 라이브러리를 지정합니다.
- Request.source()는 DSL인 매개변수를 준비합니다.
- QueryBuilders를 통해 쿼리 조건을 구축합니다.
- 완전한 쿼리를 구성하려면 Request.source()의 query() 메서드를 전달하세요.
- 요청을 보내고 결과를 받으세요.
- 분석 결과(외부에서 내부로, 레이어별로).
DSL 요청에 해당하는 형식
DSL 문의 구성은 쿼리, 정렬, 페이징 및 강조 표시와 같은 모든 기능을 포함하는 HighLevelRestClient의 리소스를 통해 구현됩니다.
그 중 쿼리(Query)는 쿼리(Query)를 의미하며, 이에 대한 쿼리 조건은 다양한 쿼리 메소드를 포함한 QueryBuilders의 툴 클래스에서 제공됩니다.
응답 분석
응답 분석은 다음과 같습니다.Kibana에서 쿼리 결과를 비교하여 API 호출 관계를 확인할 수 있습니다.
1.1.2 전문 검색 질의
전체 텍스트 검색을 위한 match 및 multi_match 쿼리는 앞서 설명한 match_all이 호출하는 API와 기본적으로 동일하며, 차이점은 쿼리 조건, 즉 쿼리 부분(QueryBuilders를 통해 구축한 조건이 다름)이다.
@Test
public void testMatch() throws IOException {
//1.准备 SearchRequest
SearchRequest request = new SearchRequest("hotel");
//2.准备参数
request.source().query(QueryBuilders.matchQuery("brand", "如家"));
//3.发送请求,并接收响应
SearchResponse response = client.search(request, RequestOptions.DEFAULT);
//4.解析响应
handlerResponse(response);
}
multi_match의 경우에도 마찬가지이지만 여러 매개변수 쿼리를 지원할 수 있습니다.
@Test
public void testMultiMatch() throws IOException {
//1.准备 SearchRequest
SearchRequest request = new SearchRequest("hotel");
//2.准备参数
request.source().query(QueryBuilders.multiMatchQuery("如家", "brand", "name"));
//3.发送请求,并接收响应
SearchResponse response = client.search(request, RequestOptions.DEFAULT);
//4.解析响应
handlerResponse(response);
}
작업 결과:
1.1.3 정확한 질의
일반적인 정밀 쿼리에는 QueryBuilders를 사용하여 구현되는 용어 쿼리 및 범위 쿼리가 포함됩니다.
@Test
public void testTerm() throws IOException {
//1.准备 SearchRequest
SearchRequest request = new SearchRequest("hotel");
//2.准备参数
request.source().query(QueryBuilders.termQuery("city", "上海"));
//3.发送请求,并接收响应
SearchResponse response = client.search(request, RequestOptions.DEFAULT);
//4.解析响应
handlerResponse(response);
}
범위 쿼리도 마찬가지입니다.
@Test
public void testRange() throws IOException {
//1.准备 SearchRequest
SearchRequest request = new SearchRequest("hotel");
//2.准备参数
request.source().query(QueryBuilders.rangeQuery("price").gte(100).lte(200)); //链式调用
//3.发送请求,并接收响应
SearchResponse response = client.search(request, RequestOptions.DEFAULT);
//4.解析响应
handlerResponse(response);
}
1.1.4 복합 쿼리
부울 쿼리는 하나 이상의 쿼리 절의 조합입니다. 하위 쿼리는 다음과 같은 방법으로 결합될 수 있습니다.
- must: 일치해야 하는 쿼리 조건으로 "and"와 유사합니다.
- should: 선택적 매칭을 위한 쿼리 조건으로 "or"와 유사합니다.
- must_not: 일치하지 않아야 하며, 채점에 참여하지 않습니다. "not"과 유사합니다.
- 필터: 일치해야 함, 채점에 참여하지 않음
RestAPI는 위의 조건을 추가하기 위해 BoolQueryBuilder 조건부 생성 방법도 제공합니다.
@Test
public void testBoolQuery() throws IOException {
//1.准备 SearchRequest
SearchRequest request = new SearchRequest("hotel");
//2.准备参数
BoolQueryBuilder booleanQuery = QueryBuilders.boolQuery();
booleanQuery.must(QueryBuilders.termQuery("city", "上海"));
booleanQuery.filter(QueryBuilders.rangeQuery("price").lte("200"));
request.source().query(booleanQuery); //链式调用
//3.发送请求,并接收响应
SearchResponse response = client.search(request, RequestOptions.DEFAULT);
//4.解析响应
handlerResponse(response);
}
1.1.5 정렬 및 페이징
검색결과의 정렬 및 페이징은 쿼리와 동일한 수준의 파라미터이며, 해당 API는 다음과 같습니다.
@Test
public void testFromSize() throws IOException {
//1.准备 SearchRequest
SearchRequest request = new SearchRequest("hotel");
//2.准备参数
request.source().query(QueryBuilders.matchAllQuery());
//分页 offset=20 size=10
request.source().from(20).size(10);
//降序排序
request.source().sort("price", SortOrder.DESC);
//3.发送请求,并接收响应
SearchResponse response = client.search(request, RequestOptions.DEFAULT);
//4.解析响应
handlerResponse(response);
}
1.1.6, 하이라이트
강조 표시된 API에는 요청 구성 DSL 문과 결과 구문 분석이라는 두 부분이 포함됩니다.
요청은 다음과 같이 구성됩니다.
@Test
public void testHighLighter() throws IOException {
//1.准备 SearchRequest
SearchRequest request = new SearchRequest("hotel");
//2.准备参数
request.source().query(QueryBuilders.matchQuery("brand", "如家"));
request.source().highlighter(new HighlightBuilder()
.field("name")
.requireFieldMatch(false));
//3.发送请求,并接收响应
SearchResponse response = client.search(request, RequestOptions.DEFAULT);
//4.解析响应
handlerResponse(response);
}
응답은 다음과 같이 구문 분석됩니다.
private void handlerResponse(SearchResponse response) throws JsonProcessingException {
//1.解析结果
SearchHits hits = response.getHits();
//获取总条数
long total = hits.getTotalHits().value;
SearchHit[] hits1 = hits.getHits();
for(SearchHit searchHit : hits1) {
//获取source
String json = searchHit.getSourceAsString();
System.out.println(json);
//2.处理高亮
//获取高亮
Map<String, HighlightField> highlightFieldMap = searchHit.getHighlightFields();
if(!CollectionUtils.isEmpty(highlightFieldMap)) {
//获取高亮字段的 value
HighlightField highlightField = highlightFieldMap.get("name");
if(highlightField != null) {
//取出高亮结果数组中的第一个,这里是酒店名称
String name = highlightField.getFragments()[0].string();
//对高亮字段的处理(这里打印做演示)
System.out.println(name);
}
}
}
}
실행 후 soout를 통해 인쇄된 "강조 표시된" 필드를 볼 수 있습니다. (마지막으로 프런트 엔드로 전송되어 프런트 엔드가 강조 표시를 처리할 수 있습니다. 백 엔드는 강조 표시해야 할 필드를 표시합니다.)