21-RestClient查询文档-排序、分页和高亮

发布时间 2023-05-23 15:23:33作者: JustJavaIt

排序、分页

搜索结果的排序和分页是与query同级的参数,因此同样是使用request.source()来设置。

对应的API如下:

完整代码示例

 1 @Test
 2     void testSortAndPage() throws IOException {
 3         int page = 2, size = 5;
 4 
 5         // 1.准备request
 6         SearchRequest request = new SearchRequest("hotel");
 7         // 2.准备请求参数
 8         // 2.1.query
 9         request.source()
10                 .query(QueryBuilders.matchAllQuery());
11         // 2.2.排序sort
12         request.source().sort("price", SortOrder.ASC);
13         // 2.3.分页 from\size
14         request.source().from((page - 1) * size).size(size);
15 
16         // 3.发送请求,得到响应
17         SearchResponse response = client.search(request, RequestOptions.DEFAULT);
18         // 4.结果解析
19         handleResponse(response);
20     }
View Code

 高亮

高亮的代码与之前代码差异较大,有两点:

(1)查询的DSL:其中除了查询条件,还需要添加高亮条件,同样是与query同级。

(2)结果解析:结果除了要解析_source文档数据,还要解析高亮结果。

高亮请求构建

高亮请求的构建API如下:

上述代码省略了查询条件部分,但是大家不要忘了:高亮查询必须使用全文检索查询,并且要有搜索关键字,将来才可以对关键字高亮。

完整代码
 1 @Test
 2     void testHighlight() throws IOException {
 3         // 1.准备request
 4         SearchRequest request = new SearchRequest("hotel");
 5         // 2.准备请求参数
 6         // 2.1.query  高亮查询必须使用全文检索查询,并且要有搜索关键字,将来才可以对关键字高亮
 7         request.source().query(QueryBuilders.matchQuery("all", "外滩如家"));
 8         // 2.2.高亮
 9         request.source().highlighter(new HighlightBuilder().field("name").requireFieldMatch(false));
10         // 3.发送请求,得到响应
11         SearchResponse response = client.search(request, RequestOptions.DEFAULT);
12         // 4.结果解析
13         handleResponse(response);
14     }
View Code

高亮结果解析

高亮的结果与查询的文档结果默认是分离的,并不在一起。因此解析高亮的代码需要额外处理:

代码解读:

  • 第一步:从结果中获取source。hit.getSourceAsString(),这部分是非高亮结果,json字符串。还需要反序列为HotelDoc对象

  • 第二步:获取高亮结果。hit.getHighlightFields(),返回值是一个Map,key是高亮字段名称,值是HighlightField对象,代表高亮值

  • 第三步:从map中根据高亮字段名称,获取高亮字段值对象HighlightField

  • 第四步:从HighlightField中获取Fragments,并且转为字符串。这部分就是真正的高亮字符串了

  • 第五步:用高亮的结果替换HotelDoc中的非高亮结果

完整代码
 1  private void handleResponse(SearchResponse response) {
 2         SearchHits searchHits = response.getHits();
 3         // 4.1.总条数
 4         long total = searchHits.getTotalHits().value;
 5         System.out.println("总条数:" + total);
 6         // 4.2.获取文档数组
 7         SearchHit[] hits = searchHits.getHits();
 8         // 4.3.遍历
 9         for (SearchHit hit : hits) {
10             // 4.4.获取source
11             String json = hit.getSourceAsString();
12             // 4.5.反序列化,非高亮的
13             HotelDoc hotelDoc = JSON.parseObject(json, HotelDoc.class);
14             // 4.6.处理高亮结果
15             // 1)获取高亮map
16             Map<String, HighlightField> map = hit.getHighlightFields();
17             // 2)根据字段名,获取高亮结果
18             HighlightField highlightField = map.get("name");
19 
20             if(null != highlightField){
21                 // 3)获取高亮结果字符串数组中的第1个元素
22                 String hName = highlightField.getFragments()[0].toString();
23                 // 4)把高亮结果放到HotelDoc中
24                 hotelDoc.setName(hName);
25             }
26             // 4.7.打印
27             System.out.println(hotelDoc);
28         }
29     }
View Code