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

 

结果展示:

 

posted @ 2024-04-19 11:21  一介桃白白  阅读(36)  评论(0编辑  收藏  举报