SpringCloud(七.6)ES(elasticsearch)-- RestClient查询文档和结果处理
- 快速入门 match_all 查询全部
- match查询
- 精确查询
- 复合查询
- 排序、分页、高亮
准备工作:初始化JavaRestClient
和 SpringCloud(七.3)ES(elasticsearch)-- RestClient操作索引库、文档 步骤一样
1、引入ES的RestHighLevelClient依赖
<!--elasticsearch--> <dependency> <groupId>org.elasticsearch.client</groupId> <artifactId>elasticsearch-rest-high-level-client</artifactId> </dependency>
2、统一ES版本,因为SpringBoot默认的ES版本是7.6.2,所以我们需要覆盖默认的ES版本
<properties> <java.version>1.8</java.version> <elasticsearch.version>7.12.1</elasticsearch.version> </properties>
3、初始化RestHighLevelClient(连接到ES和释放掉ES)
@SpringBootTest class HotelSearchTest { private RestHighLevelClient client; @BeforeEach void setUp() { client = new RestHighLevelClient(RestClient.builder( HttpHost.create("http://192.168.223.129:9200") )); } @AfterEach void tearDown() throws IOException { client.close(); } }
这些准备好后就可以编写 RestClient查询文档和结果处理 相关代码了
1.1、快速入门 match_all 查询全部
@SpringBootTest class HotelSearchTest { private RestHighLevelClient client; @Test void testMatchAll() throws IOException { // 1.准备request hotel为索引库名称 SearchRequest request = new SearchRequest("hotel"); // 2.准备请求参数 request.source().query(QueryBuilders.matchAllQuery()); // 3.发送请求,得到响应 SearchResponse response = client.search(request, RequestOptions.DEFAULT); // 4.结果打印 System.out.println(response); } @BeforeEach void setUp() { client = new RestHighLevelClient(RestClient.builder( HttpHost.create("http://192.168.223.129:9200") )); } @AfterEach void tearDown() throws IOException { client.close(); } }
结果展示:
1.2、数据结果解析
1.1中response中已经获取到了我们要查的信息,拿到的结果如何解析??数据如何使用???
封装一下结果解析的工作
private void handleResponse(SearchResponse response) { SearchHits searchHits = response.getHits(); // 4.1.总条数 long total = searchHits.getTotalHits().value; System.out.println("总条数:" + total); // 4.2.获取文档数组 SearchHit[] hits = searchHits.getHits(); // 4.3.遍历 for (SearchHit hit : hits) { // 4.4.获取source String json = hit.getSourceAsString(); // 4.5.反序列化 HotelDoc hotelDoc = JSON.parseObject(json, HotelDoc.class); // 4.6.打印 System.out.println(hotelDoc); } }
1.1代码优化后
@Test void testMatchAll() throws IOException { // 1.准备request hotel为索引库名称 SearchRequest request = new SearchRequest("hotel"); // 2.准备请求参数 request.source().query(QueryBuilders.matchAllQuery()); // 3.发送请求,得到响应 SearchResponse response = client.search(request, RequestOptions.DEFAULT); // 4.结果解析 handleResponse(response); } private void handleResponse(SearchResponse response) { SearchHits searchHits = response.getHits(); // 4.1.总条数 long total = searchHits.getTotalHits().value; System.out.println("总条数:" + total); // 4.2.获取文档数组 SearchHit[] hits = searchHits.getHits(); // 4.3.遍历 for (SearchHit hit : hits) { // 4.4.获取source String json = hit.getSourceAsString(); // 4.5.反序列化 HotelDoc hotelDoc = JSON.parseObject(json, HotelDoc.class); // 4.6.打印 System.out.println(hotelDoc); } }
结果展示:(这里我们发现结果只显示了十条 在 SpringCloud(七.5)ES(elasticsearch)-- 查询结果处理 分页 那我们学习了ES做了处理默认展示10条)
重点小结:
前三步中有两个核心的api功能要注意
1、source
2、QueryBuilders
2、match查询
@Test void testMatch() throws IOException { // 1.准备request SearchRequest request = new SearchRequest("hotel"); // 2.准备请求参数 request.source().query(QueryBuilders.matchQuery("all", "如家"));//match查询(单字段查询) //request.source().query(QueryBuilders.multiMatchQuery("如家", "name", "brand", "city"));//multi_match查询(多字段查询) // 3.发送请求,得到响应 SearchResponse response = client.search(request, RequestOptions.DEFAULT); // 4.结果解析 handleResponse(response); }
结果展示:
3、精确查询
精确查询和match查询几乎一样,只是QueryBuilders . 后面的用法不同。 这里就不一一演示了。
4、复合查询
写法一:
@Test void testBool() throws IOException { // 1.准备request SearchRequest request = new SearchRequest("hotel"); // 2.准备请求参数 //复合查询 BoolQueryBuilder boolQuery = QueryBuilders.boolQuery(); // 2.1.must boolQuery.must(QueryBuilders.termQuery("city", "上海")); // 2.2.filter boolQuery.filter(QueryBuilders.rangeQuery("price").lte(250)); request.source().query(boolQuery); // 3.发送请求,得到响应 SearchResponse response = client.search(request, RequestOptions.DEFAULT); // 4.结果解析 handleResponse(response); }
写法二:
@Test void testBool() throws IOException { // 1.准备request SearchRequest request = new SearchRequest("hotel"); // 2.准备请求参数 //复合查询 // BoolQueryBuilder boolQuery = QueryBuilders.boolQuery(); // // 2.1.must // boolQuery.must(QueryBuilders.termQuery("city", "上海")); // // 2.2.filter // boolQuery.filter(QueryBuilders.rangeQuery("price").lte(250)); // request.source().query(boolQuery); request.source().query( QueryBuilders.boolQuery() .must(QueryBuilders.termQuery("city", "上海")) .filter(QueryBuilders.rangeQuery("price").lte(250)) ); // 3.发送请求,得到响应 SearchResponse response = client.search(request, RequestOptions.DEFAULT); // 4.结果解析 handleResponse(response); }
结果展示:
5、排序、分页
@Test void testSortAndPage() throws IOException { int page = 2,size = 5; // 1.准备request SearchRequest request = new SearchRequest("hotel"); // 2.准备请求参数 // 2.1.query request.source() .query(QueryBuilders.matchAllQuery()); // 2.2.排序sort request.source().sort("price", SortOrder.ASC); // 2.3.分页 from\size 注意页数的下标from是从0开始 request.source().from((page - 1) * size).size(size); // 3.发送请求,得到响应 SearchResponse response = client.search(request, RequestOptions.DEFAULT); // 4.结果解析 handleResponse(response); }
结果展示:
6、高亮
优化 结果解析方法 handleResponse 添加上高亮结果处理相关解析
private void handleResponse(SearchResponse response) { SearchHits searchHits = response.getHits(); // 4.1.总条数 long total = searchHits.getTotalHits().value; System.out.println("总条数:" + total); // 4.2.获取文档数组 SearchHit[] hits = searchHits.getHits(); // 4.3.遍历 for (SearchHit hit : hits) { // 4.4.获取source String json = hit.getSourceAsString(); // 4.5.反序列化,非高亮的 HotelDoc hotelDoc = JSON.parseObject(json, HotelDoc.class); // 4.6.处理高亮结果 // 1)获取高亮map Map<String, HighlightField> map = hit.getHighlightFields(); // 2)根据字段名,获取高亮结果 if(!map.isEmpty()) { HighlightField highlightField = map.get("name"); if(highlightField!=null) { // 3)获取高亮结果字符串数组中的第1个元素 String hName = highlightField.getFragments()[0].toString(); // 4)把高亮结果放到HotelDoc中 hotelDoc.setName(hName); } } // 4.7.打印 System.out.println(hotelDoc); } }
高亮测试方法: 如果前端定义的标签叫其它名字,这时就需要进行指定标签 preTags 前置标签 postTags 后置标签 和DSL中一致
@Test void testHighlight() throws IOException { // 1.准备request SearchRequest request = new SearchRequest("hotel"); // 2.准备请求参数 // 2.1.query request.source().query(QueryBuilders.matchQuery("all", "外滩如家")); // 2.2.高亮 request.source().highlighter(new HighlightBuilder().field("name").requireFieldMatch(false).preTags("<em2>").postTags("</em2>")); // 3.发送请求,得到响应 SearchResponse response = client.search(request, RequestOptions.DEFAULT); // 4.结果解析 handleResponse(response); }
对比DSL
结果展示: