SpringCloud——分布式搜索elasticsearch之RestClient查询文档

前言:RestClient是Elasticsearch官方提供的一个用于与Elasticsearch集群进行通信的Java库。它提供了一组简单易用的API,我们可以使用Java代码进行与Elasticsearch的交互。


1、快速入门

我们按照以下步骤对ES进行操作,首先必须保证es已经启动,关于es安装和启动可以看:http://t.csdn.cn/NjTrg 这里只讲解如何使用java进行ES的查询操作。
使用RestClient我们可以通过以下步骤操作ES

建立连接:使用RestClient可以与Elasticsearch集群建立连接。您可以指定集群的主机和端口,以及其他可选的配置参数,例如身份验证、连接超时等。

发送请求:一旦与集群建立了连接,您可以使用RestClient发送各种类型的请求,如索引文档、执行查询、更新文档、删除文档等。您可以指定请求的HTTP方法(GET、POST、PUT、DELETE等),请求的端点路径和请求体(如果需要)。

处理响应:RestClient会发送请求并接收来自Elasticsearch的响应。您可以获取响应的状态码、头部信息和响应体,并对其进行相应的处理。您可以解析响应体中的数据、执行适当的错误处理和后续操作。

释放资源:使用完RestClient后,应该关闭它以释放资源。您可以调用close()方法来关闭与Elasticsearch集群的连接。

有关在springboot项目中引入ES部分这里也不在讲解,详情请看有关RestClient的其他操作:http://t.csdn.cn/unPoZ

以下是一个简单的示例,展示了使用RestClient与Elasticsearch进行初始化的代码:

public class HotelSearchTest {
    
    
    private RestHighLevelClient client;
    @BeforeEach
    void setUp() {
    
    
        this.client = new RestHighLevelClient(RestClient.builder(
                HttpHost.create("http://192.168.75.135:9200")
//                HttpHost.create("http://192.168.75.133:5601"), #可指定多个
//                HttpHost.create("http://192.168.75.133:5601")
        ));
    }

    //销毁客户端
    @AfterEach
    void tearDown() throws IOException {
    
    
        this.client.close();
    }    
}

下面是对上述代码的阐述:
上面代码是一个测试类的示例,用于初始化和销毁 Elasticsearch RestHighLevelClient 客户端。

扫描二维码关注公众号,回复: 17280200 查看本文章

首先,在 setUp 方法中,创建了一个 RestHighLevelClient 对象,并通过 RestClient.builder() 方法来配置 Elasticsearch 集群的连接参数。在这个例子中,指定了 Elasticsearch 集群的主机为 http://192.168.75.135,端口为 9200。
tearDown()中则是关闭ES连接的操作。

@BeforeEach、@AfterEach这两个注解用于单元测试中分别是每次执行测试之前调用和每次执行测试之后调用,这样写为了不在下文重复写连接ES和关闭ES。

match_all查询
现在我们进行一个简单的match_all查询操作,具体代码如下:

@Test
void testMatchAll() throws IOException {
    
    
    //1、准备Request
    SearchRequest request = new SearchRequest("hotel");
    //2、准备DSL
    request.source().query(QueryBuilders.matchAllQuery());
    //3、发送请求
    SearchResponse response = client.search(request, RequestOptions.DEFAULT);
    System.out.println(response);
}

查询成功:
在这里插入图片描述查询结果并没有进行格式化处理,是原始数据我们需要进行格式化操作,这是修改后的代码:

@Test
void testMatchAll() throws IOException {
    
    
    //1、准备Request
    SearchRequest request = new SearchRequest("hotel");
    //2、准备DSL
    request.source().query(QueryBuilders.matchAllQuery());
    //3、发送请求
    SearchResponse response = client.search(request, RequestOptions.DEFAULT);
    System.out.println(response);
    //4.解析响应
    SearchHits searchHits = response.getHits();
    //4.1获取数据条数
    long value = searchHits.getTotalHits().value;
    System.out.println("搜索到" + value + "条数据");
    //4.2获取具体数据
    SearchHit[] hits = searchHits.getHits();
    for (SearchHit hit : hits) {
    
    
        String json = hit.getSourceAsString();
        //反序列化
        HotelDoc hotelDoc = JSON.parseObject(json, HotelDoc.class);
        System.out.println(hotelDoc);
    }
}

结果:
在这里插入图片描述

2、MatchQuery

QueryBuilders.matchQuery(“字段名”,“查询值”)

@Test
void testMatchAndMutiMatch() throws IOException {
    
    
    //1、准备Request
    SearchRequest request = new SearchRequest("hotel");
    //2、准备DSL
    request.source().query(QueryBuilders.matchQuery("all", "如家"));
    //3、发送请求
    SearchResponse response = client.search(request, RequestOptions.DEFAULT);
    handleResponse(response);
}

private static void handleResponse(SearchResponse response) {
    
    
    //4.解析响应
    SearchHits searchHits = response.getHits();
    //4.1获取数据条数
    long value = searchHits.getTotalHits().value;
    System.out.println("搜索到" + value + "条数据");
    //4.2获取具体数据
    SearchHit[] hits = searchHits.getHits();
    for (SearchHit hit : hits) {
    
    
        String json = hit.getSourceAsString();
        //反序列化
        HotelDoc hotelDoc = JSON.parseObject(json, HotelDoc.class);
        System.out.println(hotelDoc);
    }
}

handleResponse在这里插入图片描述
是抽取的方法,不用再重复执行格式化操作。

3、termQuery和rangeQuery

void testTerm() throws IOException {
    
    
    //1、准备Request
    SearchRequest request = new SearchRequest("hotel");
    //2、准备DSL
    request.source().query(QueryBuilders.termQuery("city","北京"));
    //3、发送请求
    SearchResponse response = client.search(request, RequestOptions.DEFAULT);
    handleResponse(response);
}

@Test
void testRange() throws IOException {
    
    
    //1、准备Request
    SearchRequest request = new SearchRequest("hotel");
    //2、准备DSL
    request.source().query(QueryBuilders.rangeQuery("price").gte(100).lte(150));
    //3、发送请求
    SearchResponse response = client.search(request, RequestOptions.DEFAULT);
    handleResponse(response);
}

上文时使用term查询和range查询
在这里插入图片描述range:
在这里插入图片描述

4、BooleanQuery

  @Test
    void testBooleanQuery() throws IOException {
    
    
        //1、准备Request
        SearchRequest request = new SearchRequest("hotel");
        //2、创建布尔查询
        BoolQueryBuilder boolQueryBuilder =  new BoolQueryBuilder();

        //添加Must条件
        boolQueryBuilder.must(QueryBuilders.termQuery("city","北京"));

        //添加filter条件
        boolQueryBuilder.filter(QueryBuilders.rangeQuery("price").lte(250));
        //2、准备DSL
        request.source().query(boolQueryBuilder);
        //3、发送请求
        SearchResponse response = client.search(request, RequestOptions.DEFAULT);
        handleResponse(response);
    }

在这里插入图片描述总结:要构建查询条件只需要记住QueryBuilders

5、排序、分页、高亮

之前我们是对query进行操作的
request.source().query(QueryBuilders.matchAllQuery());

GET /hotel/_search
{
    
    
  "query": {
    
    
    "match_all": {
    
    }
  },
  "sort": [
    {
    
    
      "price": {
    
    
        "order": "asc"
      }
    }
  ],
  "from": 0,
  "size": 5
}

现在我们需要对query的同级进行操作对应java中的api也就是 source部分
具体代码:排序和分页测试

@Test
void testSortAndPage() throws IOException {
    
    
    //1、准备Request
    SearchRequest request = new SearchRequest("hotel");
    //2、准备DSL
    request.source().query(QueryBuilders.rangeQuery("price").gte(100).lte(150));
    //分页查询,使用了链式编程,
    request.source().from(0).size(5);
    //价格升序排序,这里使用了链式编程
    request.source().sort("price", SortOrder.ASC);
    //3、发送请求
    SearchResponse response = client.search(request, RequestOptions.DEFAULT);
    handleResponse(response);
}

需要注意的是我们使用链式编程。
查询结果:
在这里插入图片描述高亮测试:

@Test
void testHighLighter() throws IOException {
    
    
    //1、准备Request
    SearchRequest request = new SearchRequest("hotel");
    //2、准备DSL
    request.source().query(QueryBuilders.matchQuery("all","如家"));
    request.source().highlighter(new HighlightBuilder()
            .field("name")//高亮的字段
            .requireFieldMatch(false));//关闭精确匹配
    //3、发送请求
    SearchResponse response = client.search(request, RequestOptions.DEFAULT);
    handleResponse(response);
}


private static void handleResponse(SearchResponse response) {
    
    
    //4.解析响应
    SearchHits searchHits = response.getHits();
    //4.1获取数据条数
    long value = searchHits.getTotalHits().value;
    System.out.println("搜索到" + value + "条数据");
    //4.2获取具体数据
    SearchHit[] hits = searchHits.getHits();
    for (SearchHit hit : hits) {
    
    
        String json = hit.getSourceAsString();
        //反序列化
        HotelDoc hotelDoc = JSON.parseObject(json, HotelDoc.class);
        //获取高亮结果
        Map<String, HighlightField> highlightFields = hit.getHighlightFields();
        if (!CollectionUtils.isEmpty(highlightFields)){
    
    
            //根据名字获取高亮结果
            HighlightField highlightField = highlightFields.get("name");
            if (highlightField != null){
    
    
                //获取高亮值
                String name = highlightField.getFragments()[0].toString();
                hotelDoc.setName(name);
            }
        }
        System.out.println(hotelDoc);
    }
}

在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/qq_52227892/article/details/131095960