【Elasticsearch】Springboot编写Elasticsearch的RestAPI

RestAPI

ES官方提供了各种不同语言的客户端,用来操作ES。这些客户端的本质就是组装DSL语句,通过http请求发送给ES。
官方文档地址

由于ES目前最新版本是8.8,提供了全新版本的客户端,老版本的客户端已经被标记为过时。而我们采用的是7.12版本,因此只能使用老版本客户端:

然后选择7.12版本,HighLevelRestClient版本

初始化RestClient

在elasticsearch提供的API中,与elasticsearch一切交互都封装在一个名为RestHighLevelClient的类中,必须先完成这个对象的初始化,建立与elasticsearch的连接。

分为三步:

1)在item-service模块中引入es的RestHighLevelClient依赖:

复制代码
<dependency>
    <groupId>org.elasticsearch.client</groupId>
    <artifactId>elasticsearch-rest-high-level-client</artifactId>
</dependency>

2)因为SpringBoot默认的ES版本是7.17.10,所以我们需要覆盖默认的ES版本:

复制代码
  <properties>
      <maven.compiler.source>11</maven.compiler.source>
      <maven.compiler.target>11</maven.compiler.target>
      <elasticsearch.version>7.12.1</elasticsearch.version>
  </properties>

3)测试代码:

复制代码
@Slf4j
@SpringBootTest
class EsClientTest {

    private RestHighLevelClient client;

    @Test
    void test() throws IOException {
        log.info("client = {}",client);
    }

   @BeforeEach
    void setUp() {
       client = new RestHighLevelClient(RestClient.builder(new HttpHost("49.233.155.186", 9200, "http")));
   }

   @AfterEach
    void tearDown() throws IOException {
       if (client != null) {
           client.close();
       }
   }
}

创建索引库

由于要实现对商品搜索,所以我们需要将商品添加到Elasticsearch中,不过需要根据搜索业务的需求来设定索引库结构,而不是一股脑的把MySQL数据写入Elasticsearch.

Mapping映射

搜索页面的效果如图所示:

实现搜索功能需要的字段包括三大部分:

  • 搜索过滤字段
    • 分类
    • 品牌
    • 价格
  • 排序字段
    • 默认:按照更新时间降序排序
    • 销量
    • 价格
  • 展示字段
    • 商品id:用于点击后跳转
    • 图片地址
    • 是否是广告推广商品
    • 名称
    • 价格
    • 评价数量
    • 销量
      对应的商品表结构如下,索引库无关字段已经划掉:

      结合数据库表结构,以上字段对应的mapping映射属性如下:
字段名 字段类型 类型说明 是否参与搜索 是否参与分词 分词器
id long 长整数 [x] []
name text 字符串,参与分词搜索 [x] [x] IK
price integer 以分为单位,所以是整数 [x] []
stock integer 字符串,但需要分词 [x] []
image keyword 字符串,但是不分词 [] []
category keyword 字符串,但是不分词 [x] []
brand keyword 字符串,但是不分词 [x] []
sold integer 销量,整数 [x] []
commentCount integer 评价,整数 [] []
isAD boolean 布尔类型 [x] []
updateTime Date 更新时间 [x] []

因此,最终我们的索引库文档结构应该是这样:

复制代码
PUT /items
{
  "mappings": {
    "properties": {
      "id": {
        "type": "keyword"
      },
      "name":{
        "type": "text",
        "analyzer": "ik_max_word"
      },
      "price":{
        "type": "integer"
      },
      "stock":{
        "type": "integer"
      },
      "image":{
        "type": "keyword",
        "index": false
      },
      "category":{
        "type": "keyword"
      },
      "brand":{
        "type": "keyword"
      },
      "sold":{
        "type": "integer"
      },
      "commentCount":{
        "type": "integer",
        "index": false
      },
      "isAD":{
        "type": "boolean"
      },
      "updateTime":{
        "type": "date"
      }
    }
  }
}

创建索引

创建索引库的API如下:

代码分为三步:

  1. 创建Request对象。
    因为是创建索引库的操作,因此Request是CreateIndexRequest。

  2. 添加请求参数
    其实就是Json格式的Mapping映射参数。因为json字符串很长,这里是定义了静态字符串常量MAPPING_TEMPLATE,让代码看起来更加优雅。

  3. 发送请求
    client.indices()方法的返回值是IndicesClient类型,封装了所有与索引库操作有关的方法。例如创建索引、删除索引、判断索引是否存在等
    测试类中,具体代码如下:

    @Test
    void testCreateIndex() throws IOException {
    // 1.创建Request对象
    CreateIndexRequest request = new CreateIndexRequest("items");
    // 2.准备请求参数
    request.source(MAPPING_TEMPLATE, XContentType.JSON);
    // 3.发送请求
    client.indices().create(request, RequestOptions.DEFAULT);
    }

    static final String MAPPING_TEMPLATE = "{\n" +
    " "mappings": {\n" +
    " "properties": {\n" +
    " "id": {\n" +
    " "type": "keyword"\n" +
    " },\n" +
    " "name":{\n" +
    " "type": "text",\n" +
    " "analyzer": "ik_max_word"\n" +
    " },\n" +
    " "price":{\n" +
    " "type": "integer"\n" +
    " },\n" +
    " "stock":{\n" +
    " "type": "integer"\n" +
    " },\n" +
    " "image":{\n" +
    " "type": "keyword",\n" +
    " "index": false\n" +
    " },\n" +
    " "category":{\n" +
    " "type": "keyword"\n" +
    " },\n" +
    " "brand":{\n" +
    " "type": "keyword"\n" +
    " },\n" +
    " "sold":{\n" +
    " "type": "integer"\n" +
    " },\n" +
    " "commentCount":{\n" +
    " "type": "integer"\n" +
    " },\n" +
    " "isAD":{\n" +
    " "type": "boolean"\n" +
    " },\n" +
    " "updateTime":{\n" +
    " "type": "date"\n" +
    " }\n" +
    " }\n" +
    " }\n" +
    "}";

判断索引库是否存在

判断索引库是否存在,本质就是查询,对应的请求语句是:

复制代码
GET /索引库

因此与,流程如下:

  • 1)创建Request对象。这次是GetIndexRequest对象

  • 2)准备参数。这里是无参,直接省略

  • 3)发送请求。改用exists方法

    @Test
    void testExistsIndex() throws IOException {
    // 1.创建Request对象
    GetIndexRequest request = new GetIndexRequest("items");
    // 2.发送请求
    boolean exists = client.indices().exists(request, RequestOptions.DEFAULT);
    // 3.输出
    System.err.println(exists ? "索引库已经存在!" : "索引库不存在!");
    }

删除索引库

删除索引库的请求非常简单:

复制代码
DELETE /索引库

与创建索引库相比:

  • 请求方式从PUT变为DELTE
  • 请求路径不变
  • 无请求参数

所以代码的差异,注意体现在Request对象上。流程如下:

  • 1)创建Request对象。这次是DeleteIndexRequest对象
  • 2)准备参数。这里是无参,因此省略
  • 3)发送请求。改用delete方法

编写单元测试,实现删除索引:

复制代码
@Test
void testDeleteIndex() throws IOException {
    // 1.创建Request对象
    DeleteIndexRequest request = new DeleteIndexRequest("items");
    // 2.发送请求
    client.indices().delete(request, RequestOptions.DEFAULT);
}

总结

JavaRestClient操作elasticsearch的流程基本类似。核心是client.indices()方法来获取索引库的操作对象。

索引库操作的基本步骤:

  • 初始化RestHighLevelClient
  • 创建XxxIndexRequest。XXX是Create、Get、Delete
  • 准备请求参数( Create时需要,其它是无参,可以省略)
  • 发送请求。调用RestHighLevelClient#indices().xxx()方法,xxx是create、exists、delete
相关推荐
Elasticsearch12 分钟前
如何比较两个 Elasticsearch 索引并找出缺失的文档
elasticsearch
海兰17 分钟前
使用 Elastic Workflows 监控 Kibana 仪表板访问数据
android·人工智能·elasticsearch·rxjava
5720 天窗1 小时前
classfinal加密Spring boot3
java·spring boot·后端·classfinal·class final
希望永不加班2 小时前
SpringBoot 整合 Elasticsearch 实现全文检索
java·spring boot·后端·elasticsearch·全文检索
risc1234562 小时前
【Elasticsearch】副本分片(Replica Shard)的 globalCheckpoint 更新与推进机制
elasticsearch
希望永不加班2 小时前
SpringBoot 多模块项目搭建:service/dao/web分层设计
java·前端·spring boot·后端·spring
星晨雪海2 小时前
springboot 增删改查全套流程
java·spring boot·spring
Devin~Y2 小时前
高并发内容社区实战面试:从 Java 基础到 Spring Cloud、Kafka、Redis、RAG 搜索全解析
java·spring boot·redis·spring cloud·kafka·向量数据库·rag
star-yp2 小时前
vibe coding 博客管理系统
java·spring boot·spring·ai·ai编程
小江的记录本2 小时前
【JEECG Boot】JEECG Boot 系统性知识体系全方位结构化总结
java·前端·spring boot·后端·python·spring·spring cloud