目录
接下里通过一个 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);
- }
- }
由上可以看出查询的基本步骤如下:

DSL 语句的构建是通过 HighLevelRestClient 中的 Resource 实现的,其中包含了 查询、排序】分页、高亮等所有功能.

其中 query 表示查询的意思,他的查询条件的是由 QueryBuilders 的工具类提供的,包含了各种查询方法.


响应解析这里,可以在 Kibana 上通过查询结果,对比着看出 API 的调用关系.
全文检索的 match 和 multi_match 查询和前面演示的 match_all 调用的 API 基本一致,差别就是查询条件,也就是 query 部分(通过 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);
- }

运行结果:

精确查询常见的有 term 查询 和 range 查询,同样利用 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);
- }

range 查询也是如此.
- @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);
- }

布尔查询是一个或多个查询子句的组合. 子查询的组合方式有:
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);
- }

对于搜索结果的排序和分页与 query 是同级参数,对应 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);
- }

高亮的 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
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);
- }
- }
- }
- }

运行后可以看到通过 sout 打印出的“高亮”字段(最后会传输给前端 ,让前端处理高亮. 后端只是标记出了哪些字段需要高亮处理)

