16、全文检索 -- Elasticsearch -- 使用 RESTful 客户端 ( 就是RestClient) 操作Es(通过 RestHighLevelClient 增、删、查索引库及文档)

RestHighLevelClient 用法示例(创建、删除、查询索引库;添加、查询、删除文档)


1、启动 Elasticsearch 服务器:

打开命令行窗口(小黑窗),输入命令: elasticsearch ,即可启动 Elasticsearch 服务器

在这里插入图片描述

2、因为去掉SSL证书验证,所以向Elasticsearch服务器发送请求的时候,是使用 http 协议。


RestHighLevelClient 相关介绍


Spring Boot 只要检测到类路径下有 elasticsearch-rest-high-level-client 依赖(无需Spring Data Elasticsearch),Spring Boot 就会在容器中创建一个自动配置的 RestHighLevelClient,它就是Elasticsearch 的高级 RestClient 客户端。

在这里插入图片描述

当容器中有了这个自动配置的 RestHighLevelClient (高级RestClient)之后,我们(或者说容器)就可以将它注入到其他任何组件(主要是DAO组件),通过它来操作 Elasticsearch 索引库。



测试类——代码演示:


去掉 SSL 证书验证


让项目通过 HTTPS 连接 Elasticsearch 的配置

把这个存放公钥证书的密钥库删掉

在这里插入图片描述


配置文件不启动SSL 证书验证

在这里插入图片描述


配置文件里面,用 http 连接就可以了,不需要用 https 连接。

在这里插入图片描述


ElasticsearchConfig 类里面的一些定制也注释掉

在这里插入图片描述


重启 Elasticsearch 服务器。
就是打开小黑窗,也就是命令行窗口,输入:elasticsearch 即可启动服务器。

在这里插入图片描述



1、创建 index 索引库


我原先使用的Elasticsearch的依赖版本是7.14.1,但是测试的时候报错,提示elasticsearchRestHighLevelClient这个bean创建失败,所以 修改依赖版本为7.12.0 就好了


代码

在这里插入图片描述


测试结果

在这里插入图片描述


通过 postman 发送 http://localhost:9200/_cat/indices 查询所有索引库,可以看到创建索引库成功

在这里插入图片描述


查看指定索引库:http://localhost:9200/books/

在这里插入图片描述


2、删除 index 索引库


代码

在这里插入图片描述


测试结果

如图,刚刚添加的三个索引库,只剩下 books 这个索引库了
删除索引库成功

在这里插入图片描述


3、查询所有 index 索引库


代码和结果

成功查询出Elasticsearch服务器里面的所有索引库


在这里插入图片描述


4、往索引库里面添加文档


代码演示:

在这里插入图片描述


测试结果

查询指定索引库的所有文档:http://localhost:9200/books/_search

_search 的作用就是查看该索引库的所有文档

如图:往索引库添加文档成功


在这里插入图片描述


如果查询条件不加 _search,则只是查询该索引库的配置
如图:http://localhost:9200/books 不加 _search,查出来是索引库的基本数据配置之类的。

在这里插入图片描述


5、根据索引库内文档的id查询文档


代码和结果

如图:根据文档的id查询文档成功。


在这里插入图片描述


6、根据条件查询文档(通配符和关键字)


代码

在这里插入图片描述


测试结果

普通关键字查询和通配符查询都能正确查询出来


在这里插入图片描述


7、根据 id 删除文档


代码

在这里插入图片描述


测试结果

查询 books 索引库的全部文档:http://localhost:9200/books/_search
可以看到id 为 3 和 4 的文档已经被成功删除了。


在这里插入图片描述



具体代码


在这里插入图片描述


ElasticsearchConfig 配置类


这个配置类一开始是设置密钥库的路径和密码,作用是让 SpringBoot 应用可以根据该 trustStore 中保存的证书去信任目标服务器(Elasticsearch 服务器)的 SSL 证书。
但是后面测试为了方便使用了http协议发送请求,所以就没有用到ssl自签名证书。
在这篇文章的测试中,并没有用到这个配置类。


package cn.ljh.restclient.config;

import org.apache.http.client.config.RequestConfig;
import org.apache.http.conn.ssl.NoopHostnameVerifier;
import org.apache.http.impl.nio.client.HttpAsyncClientBuilder;
import org.elasticsearch.client.RestClientBuilder;
import org.springframework.boot.autoconfigure.elasticsearch.RestClientBuilderCustomizer;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.io.File;

/**
 *  author JH  2024-02
 *  trustStore 是一个专门存密钥的一个库 ,这里只用来存 Elasticsearch 的公钥证书,所以把这个密钥库叫: elastic.store
 */

@Configuration(proxyBeanMethods = false)
public class ElasticsearchConfig
{
    //设置密钥库的路径和密码,作用是让 SpringBoot 应用可以根据该 trustStore 中保存的证书去信任目标服务器(Elasticsearch 服务器)的 SSL 证书
//    static
//    {
//        // 获取elastic.store的保存位置
//        String storePath = new File(
//                ApplicationContext.class
//                        .getResource("/")
//                        .getFile()
//        )
//                .getParentFile()
//                .getAbsolutePath() + "\\classes\\elastic.store";
//
//        // 设置trustStore的位置,设置要信任的密钥库的路径
//        System.setProperty("javax.net.ssl.trustStore", storePath);
//
//        // 设置trustStore的读取密码
//        System.setProperty("javax.net.ssl.trustStorePassword", "123456");
//    }

    //对 RestClientBuilderCustomizer 进行定制,主要是为了设置验证目标服务器的证书时,不验证主机名
    @Bean
    public RestClientBuilderCustomizer restClientBuilderCustomizer()
    {
        return new RestClientBuilderCustomizer()
        {
            @Override
            public void customize(RestClientBuilder builder)
            {
                //此处可对 RestClientBuilder 进行定制
            }

            @Override
            public void customize(HttpAsyncClientBuilder builder)
            {
                // 对 HttpAsyncClientBuilder 进行定制

                // 因为此时演示的Elasticsearch 目标服务器的主机地址,就是本机的 IP 地址,
                // 所以验证目标服务器的证书时,这台服务器的主机名依然无法通过证书验证

                // 设置验证目标服务器的证书时,不验证主机名
                builder.setSSLHostnameVerifier(NoopHostnameVerifier.INSTANCE);
            }

            @Override
            public void customize(RequestConfig.Builder builder)
            {
                //此处可对 RequestConfig.Builder 进行定制
            }
        };

    }
}

application.properties 配置文件


# 配置Elasticsearch的连接

# 指定ElasticSearch服务器的地址(可以列出多个节点的地址)
spring.elasticsearch.rest.uris=http://127.0.0.1:9200
spring.elasticsearch.rest.read-timeout=10s

# 配置用户名和密码
spring.elasticsearch.rest.username=elastic
spring.elasticsearch.rest.password=123456


RestHighLevelClientTest 测试类代码演示


package cn.ljh.restclient;

import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import lombok.SneakyThrows;
import org.elasticsearch.action.admin.indices.delete.DeleteIndexRequest;
import org.elasticsearch.action.delete.DeleteRequest;
import org.elasticsearch.action.delete.DeleteResponse;
import org.elasticsearch.action.get.GetRequest;
import org.elasticsearch.action.get.GetResponse;
import org.elasticsearch.action.index.IndexRequest;
import org.elasticsearch.action.index.IndexResponse;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.action.support.master.AcknowledgedResponse;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.client.indices.CreateIndexRequest;
import org.elasticsearch.client.indices.CreateIndexResponse;
import org.elasticsearch.client.indices.GetIndexRequest;
import org.elasticsearch.client.indices.GetIndexResponse;
import org.elasticsearch.common.xcontent.XContentType;
import org.elasticsearch.index.query.QueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.json.JSONArray;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.CsvSource;
import org.junit.jupiter.params.provider.ValueSource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;

import java.util.Arrays;

@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.NONE)
public class RestHighLevelClientTest
{

    //用来操作 Elasticsearch 服务器的一个客户端对象类
    @Autowired
    private RestHighLevelClient restHLClient;

    //创建三个索引库
    @ParameterizedTest //参数测试
    @SneakyThrows
    @ValueSource(strings = {"books", "items", "users"})
    public void testCreateIndex(String indexName)
    {

        //指定分词器创建索引库的json格式的数据,每一行用双引号包起来,然后里面的每个双引号前面用反斜杠\转义
        String json = "{" +
                "\"settings\": {" +
                "    \"analysis\": {" +
                "      \"analyzer\": {" +
                "        \"default\": {" +
                "           \"tokenizer\": \"ik_max_word\"" +
                "        }" +
                "      }" +
                "    }" +
                "  }" +
                "}";

        CreateIndexRequest request = new CreateIndexRequest(indexName)
                //参数1:指定创建索引库时要传入的参数  ; 参数2:指定传入内容的类型
                .source(json, XContentType.JSON);
        //创建索引库后返回的响应类型--CreateIndexResponse
        CreateIndexResponse resp = restHLClient.indices().create(request, RequestOptions.DEFAULT);

        //获取Elasticsearch服务器的响应,就是响应索引库是否创建成功
        System.err.println(resp.isAcknowledged());

    }


    //删除索引库
    @SneakyThrows
    @ParameterizedTest
    @ValueSource(strings = {"items", "users"})
    public void testDeleteIndex(String indexName)
    {
        //删除索引的请求数据
        DeleteIndexRequest request = new DeleteIndexRequest(indexName);
        //客户端调用操作索引的方法,然后再调用删除的方法
        AcknowledgedResponse resp = restHLClient.indices().delete(request, RequestOptions.DEFAULT);
        //查看删除后的响应
        System.err.println(resp.isAcknowledged());
    }

    //查询所有的索引库
    @SneakyThrows
    @Test //这个测试不需要参数,直接用这个@Test注解即可
    public void testGetIndex()
    {
        //参数 "*" : 表示匹配所有的索引库
        GetIndexRequest request = new GetIndexRequest("*");
        //用rest客户端的方法来查询
        GetIndexResponse resp = restHLClient.indices().get(request, RequestOptions.DEFAULT);
        //返回的索引库是一个String类型的数组
        String[] indices = resp.getIndices();
        //把数组转成字符串
        String s = Arrays.toString(indices);
        System.err.println(s);


    }

    //往索引库添加文档

    @ParameterizedTest
    @SneakyThrows
    //测试参数有多个值 ,用这个注解
    @CsvSource({
            "1,火影忍者,旋涡鸣人成长为第七代火影的故事,150",
            "2,家庭教师,废材纲成长为十代首领的热血事迹,200",
            "4,七龙珠Z,超级赛亚人贝吉塔来到地球后的热闹景象,400"
    })
    public void testSaveDocument(Integer id, String title, String description, Double price)
    {
        //表明向 books 索引库添加文档
        IndexRequest request = new IndexRequest("books")
                .id(id + "")
                .source(
                        "title", title,
                        "description", description,
                        "price", price
                );

        IndexResponse resp = restHLClient.index(request, RequestOptions.DEFAULT);
        System.err.println(resp);

    }


    //根据文档的id获取文档
    @SneakyThrows
    @ParameterizedTest
    @ValueSource(ints = {1, 3})
    public void testGetDocumentById(Integer id)
    {
        //表明从 books 索引库获取文档
        GetRequest request = new GetRequest("books")
                //表明根据指定的文档的id获取文档
                .id(id + "");

        GetResponse resp = restHLClient.get(request, RequestOptions.DEFAULT);

        System.err.println(resp);

    }

    //根据条件查询文档(普通关键字查询和通配符查询)

    @SneakyThrows
    @ParameterizedTest
    @CsvSource({
            "description,热*",
            "description,成长"
    })
    public void testSearchDocument(String field, String term)
    {
        // 构建查询条件的类
        SearchSourceBuilder builder = new SearchSourceBuilder();

        // 通过 SearchSourceBuilder 可以用面向对象的方式来构建查询的 JSON 字符串
        // SearchSourceBuilder 需要传入 QueryBuilders,而 QueryBuilders 用于构建 QueryBuilder
        if (term != null && term.contains("*"))
        {
            //根据字段和通配符关键字查询
            builder.query(QueryBuilders.wildcardQuery(field, term));
        } else
        {
            //根据字段和普通关键字查询
            builder.query(QueryBuilders.matchQuery(field,term));
        }

        //表明从 books 索引库查询文档
        SearchRequest request = new SearchRequest("books")
                // 此处的 builder 参数用于构建查询语法
                .source(builder);

        //客户端调用查询的方法 , 参数1:查询条件语法  参数2:默认的请求选项,比如超时时间之类的
        SearchResponse resp = restHLClient.search(request, RequestOptions.DEFAULT);

        System.err.println(resp);

    }


    //根据 id 删除文档

    @ParameterizedTest
    @SneakyThrows
    @ValueSource(ints = {3,4})
    public void testDeleteDocumentById(Integer id)
    {
        //表明从 books 索引库删除文档
        DeleteRequest request = new DeleteRequest("books")
                //获取指定id的文档
                .id(id+"");
        //rest客户端调用删除文档的方法
        DeleteResponse resp = restHLClient.delete(request, RequestOptions.DEFAULT);
        System.err.println(resp);
    }



}




pom.xml 依赖文件


主要是这个 Elasticsearch 的依赖,其它的就是正常的boot项目需要的依赖

        <!-- 添加 HighLevelRest Client -->
        <dependency>
            <groupId>org.elasticsearch.client</groupId>
            <artifactId>elasticsearch-rest-high-level-client</artifactId>
            <version>7.12.0</version>
        </dependency>

完整依赖:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.5.3</version>
    </parent>

    <groupId>cn.ljh</groupId>
    <artifactId>restclient</artifactId>
    <version>1.0.0</version>
    <name>restclient</name>

    <properties>
        <java.version>11</java.version>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter</artifactId>
        </dependency>


        <!-- 添加 HighLevelRest Client -->
        <dependency>
            <groupId>org.elasticsearch.client</groupId>
            <artifactId>elasticsearch-rest-high-level-client</artifactId>
            <version>7.12.0</version>
        </dependency>

        <!-- 开发者工具 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
            <scope>runtime</scope>
            <optional>true</optional>
        </dependency>

        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <configuration>
                    <excludes>
                        <exclude>
                            <groupId>org.projectlombok</groupId>
                            <artifactId>lombok</artifactId>
                        </exclude>
                    </excludes>
                </configuration>
            </plugin>
        </plugins>
    </build>

</project>







  • 29
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
好的,下面是一个简单的示例: 1. 引入依赖 在 pom.xml 文件中添加以下依赖: ```xml <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-elasticsearch</artifactId> </dependency> ``` 2. 配置 Elasticsearch 在 application.properties 文件中添加 Elasticsearch 相关配置: ```properties spring.elasticsearch.rest.uris=http://localhost:9200 ``` 3. 定义实体类 创建一个实体类,例如: ```java @Document(indexName = "user") public class User { @Id private String id; private String name; private Integer age; // getter/setter 略 } ``` 4. 创建 Elasticsearch Repository 创建一个继承自 ElasticsearchRepository 的接口,例如: ```java public interface UserRepository extends ElasticsearchRepository<User, String> { } ``` 5. 编写改方法 在业务逻辑层中编写改方法,例如: ```java @Service public class UserService { @Autowired private UserRepository userRepository; public void save(User user) { userRepository.save(user); } public void delete(String id) { userRepository.deleteById(id); } public List<User> search(String keyword) { return userRepository.findByNameContaining(keyword); } public void update(User user) { userRepository.save(user); } } ``` 以上示例中,save 方法用于保存用户信息,delete 方法用于除用户信息,search 方法用于根据关键字搜索用户信息,update 方法用于更新用户信息。 6. 测试 编写测试类,例如: ```java @RunWith(SpringRunner.class) @SpringBootTest public class UserServiceTest { @Autowired private UserService userService; @Test public void testSave() { User user = new User(); user.setId("1"); user.setName("张三"); user.setAge(20); userService.save(user); } @Test public void testDelete() { userService.delete("1"); } @Test public void testSearch() { List<User> userList = userService.search("张三"); System.out.println(userList); } @Test public void testUpdate() { User user = new User(); user.setId("1"); user.setName("张三"); user.setAge(25); userService.update(user); } } ``` 以上示例中,testSave 方法用于测试保存用户信息,testDelete 方法用于测试除用户信息,testSearch 方法用于测试根据关键字搜索用户信息,testUpdate 方法用于测试更新用户信息。 运行测试类,看控制台输出结果,即可验证改功能是否正常。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

_L_J_H_

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值