Elasticsearch(2):JavaRestClient操作Elasticsearch全流程实战指南

JavaRestClient操作

概述

JavaRestClient用来操作ES,这些客户端的本质就是组装DSL语句,通过http请求发送给ES。

官方文档地址:

https://www.elastic.co/guide/en/elasticsearch/client/index.html

依赖:

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

注意要与es的版本一致,不要使用默认springboot的版本,可自己设置父文件的版本

初始化RestHighLevelClient:

初始化的代码如下:

Java 复制代码
RestHighLevelClient client = new RestHighLevelClient(RestClient.builder(
        HttpHost.create("http://localhost:9200")
));

可进行测试

java 复制代码
 @BeforeEach
    void setUp() {
        this.client = new RestHighLevelClient(RestClient.builder(
                HttpHost.create("http://localhost:9200")
        ));
    }

    @Test
    void testConnect() {
        System.out.println(client);
    }

    @AfterEach
    void tearDown() throws IOException {
        this.client.close();
    }

索引库操作

创建索引库

java 复制代码
@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);
}

MAPPING_TEMPLATE需要填写自己的json格式mapping要求

删除索引库

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

判断索引库是否存在

java 复制代码
@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 ? "索引库已经存在!" : "索引库不存在!");
}

查看索引库

java 复制代码
 @Test
    void GetIndex() throws IOException {
        //1、创建index判断请求
        GetIndexRequest getIndexRequest = new GetIndexRequest("items");
        //2、发送判断请求
        GetIndexResponse getIndexResponse = client.indices().get(getIndexRequest, RequestOptions.DEFAULT);
        // 3、1. 获取所有索引名
        System.out.println(getIndexResponse.getIndices());

        // 3、2. 获取 mappings
        System.out.println(getIndexResponse.getMappings());

        // 3、3 获取 settings
        System.out.println(getIndexResponse.getSettings());

        // 3、4. 获取 aliases
        System.out.println(getIndexResponse.getAliases());//3、判断是否为空

    }

总结

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

索引库操作的基本步骤:

  • 初始化RestHighLevelClient
  • 创建XxxIndexRequest。XXX是CreateGetDelete
  • 准备请求参数( Create时需要,其它是无参,可以省略)
  • 发送请求。调用RestHighLevelClient#indices().xxx()方法,xxx是createexistsdelete

文档操作

初始化

1、引入数据库方便数据引入

@SpringBootTest(properties = "spring.profiles.active=local")提供了数据库入口

2、初始化RestHighLevelClient

java 复制代码
 this.client = new RestHighLevelClient(RestClient.builder(HttpHost.create("")));

3、及时关闭连接

this.client.close();

java 复制代码
package com.hmall.item.es;

import com.hmall.item.service.IItemService;
import org.apache.http.HttpHost;
import org.elasticsearch.client.RestClient;
import org.elasticsearch.client.RestHighLevelClient;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;

import java.io.IOException;

@SpringBootTest(properties = "spring.profiles.active=local")
public class DocumentTest {

    private RestHighLevelClient client;
    @Autowired
    private IItemService itemService;

    @BeforeEach
    void setUp() {
        this.client = new RestHighLevelClient(RestClient.builder(
                HttpHost.create("")
        ));
    }
    
    @AfterEach
    void tearDown() throws IOException {
        this.client.close();
    }
}

新增文档

新增文档时要输入数据的内容,但手动输入过于繁琐

使用数据库输入更加方便

但数据库输入的数据并非全部需要,而且具有格式问题

我们需要新建doc类,将需要的属性放入

java 复制代码
@Data
@ApiModel(description = "索引库实体")
public class ItemDoc{

    @ApiModelProperty("商品id")
    private String id;

    @ApiModelProperty("商品名称")
    private String name;

    @ApiModelProperty("价格(分)")
    private Integer price;

    @ApiModelProperty("商品图片")
    private String image;

    @ApiModelProperty("类目名称")
    private String category;

    @ApiModelProperty("品牌名称")
    private String brand;

    @ApiModelProperty("销量")
    private Integer sold;

    @ApiModelProperty("评论数")
    private Integer commentCount;

    @ApiModelProperty("是否是推广广告,true/false")
    private Boolean isAD;

    @ApiModelProperty("更新时间")
    private LocalDateTime updateTime;
}

再新建时,将数据库的数据格式item使用hutool变为itemdoc,再转为json,即可使用

java 复制代码
 @Test
    void testAddDocument() throws IOException {
        // 1.根据id查询商品数据
        Item item = itemService.getById(100002644680L);
        //2、转为itemdoc
        ItemDoc itemdoc=BeanUtil.copyProperties(item,ItemDoc.class);
        System.out.println(itemdoc.getId());
        //3、转为json
        String doc=JSONUtil.toJsonStr(itemdoc);
        //4、准备request对象
        IndexRequest indexRequest = new IndexRequest("item").id(itemdoc.getId());
        //2、准备JSON文档
        indexRequest.source(doc, XContentType.JSON);
        //3、发送请求
        client.index(indexRequest, RequestOptions.DEFAULT);

    }

查询文档

Java 复制代码
@Test
void testGetDocumentById() throws IOException {
    // 1.准备Request对象
    GetRequest request = new GetRequest("items").id("100002644680");
    // 2.发送请求
    GetResponse response = client.get(request, RequestOptions.DEFAULT);
    // 3.获取响应结果中的source
    String json = response.getSourceAsString();
    
    ItemDoc itemDoc = JSONUtil.toBean(json, ItemDoc.class);
    System.out.println("itemDoc= " + ItemDoc);
}

修改文档

全局修改:与新增文档一样

如果不存在,则为index,如果存在,则为update

局部修改:

Java 复制代码
@Test
void testUpdateDocument() throws IOException {
    // 1.准备Request
    UpdateRequest request = new UpdateRequest("items", "100002644680");
    // 2.准备请求参数
    request.doc(
            "price", 58800,
            "commentCount", 1
    );
    // 3.发送请求
    client.update(request, RequestOptions.DEFAULT);
}

删除文档

Java 复制代码
@Test
void testDeleteDocument() throws IOException {
    // 1.准备Request,两个参数,第一个是索引库名,第二个是文档id
    DeleteRequest request = new DeleteRequest("item", "100002644680");
    // 2.发送请求
    client.delete(request, RequestOptions.DEFAULT);
}

批处理

我们如果要将这些数据导入索引库,肯定不能逐条导入,而是采用批处理方案。常见的方案有:

  • 利用Logstash批量导入
    • 需要安装Logstash
    • 对数据的再加工能力较弱
    • 无需编码,但要学习编写Logstash导入配置
  • 利用JavaAPI批量导入
    • 需要编码,但基于JavaAPI,学习成本低
    • 更加灵活,可以任意对数据做再加工处理后写入索引库

基于javaapi时:

BulkRequest中提供了add方法,用以添加其它CRUD的请求:

,能添加的请求有:

  • IndexRequest,也就是新增
  • UpdateRequest,也就是修改
  • DeleteRequest,也就是删除

例:

java 复制代码
@Test
void testBulk() throws IOException {
    // 1.创建Request
    BulkRequest request = new BulkRequest();
    // 2.准备请求参数
    request.add(new IndexRequest("items").id("1").source("json doc1", XContentType.JSON));
    request.add(new IndexRequest("items").id("2").source("json doc2", XContentType.JSON));
    // 3.发送请求
    client.bulk(request, RequestOptions.DEFAULT);
}

当我们插入大量数据时,需要分开插入

例:

java 复制代码
@Test
void testLoadItemDocs() throws IOException {
    // 分页查询商品数据
    int pageNo = 1;
    int size = 1000;
    while (true) {
        Page<Item> page = itemService.lambdaQuery().eq(Item::getStatus, 1).page(new Page<Item>(pageNo, size));
        // 非空校验
        List<Item> items = page.getRecords();
        if (CollUtils.isEmpty(items)) {
            return;
        }
        log.info("加载第{}页数据,共{}条", pageNo, items.size());
        // 1.创建Request
        BulkRequest request = new BulkRequest("items");
        // 2.准备参数,添加多个新增的Request
        for (Item item : items) {
            // 2.1.转换为文档类型ItemDTO
            ItemDoc itemDoc = BeanUtil.copyProperties(item, ItemDoc.class);
            // 2.2.创建新增文档的Request对象
            request.add(new IndexRequest()
                            .id(itemDoc.getId())
                            .source(JSONUtil.toJsonStr(itemDoc), XContentType.JSON));
        }
        // 3.发送请求
        client.bulk(request, RequestOptions.DEFAULT);

        // 翻页
        pageNo++;
    }
}

总结

文档操作的基本步骤:

  • 初始化RestHighLevelClient
  • 创建XxxRequest。
    • XXX是IndexGetUpdateDeleteBulk
  • 准备参数(IndexUpdateBulk时需要)
  • 发送请求。
    • 调用RestHighLevelClient#.xxx()方法,xxx是indexgetupdatedeletebulk
  • 解析结果(Get时需要)
相关推荐
zoyation1 小时前
Spring Boot多数据源
java·spring boot·后端
i220818 Faiz Ul1 小时前
在线预约导游|基于SSM+vue的在线预约导游系统(源码+数据库+文档)
java·前端·数据库·vue.js·spring boot·毕设·在线预约导游系统
兴通物联科技1 小时前
条码防重防错防漏防呆:工业数据采集的全链路风控技术方案
大数据·物联网·计算机视觉·计算机外设·硬件架构
右耳朵猫AI2 小时前
Java & JVM技术周刊 2026年第19周
java·开发语言·jvm
1candobetter2 小时前
单接口性能测试实践总结:压测方案设计、成功判定与 JVM 监控分析
java·jvm·压力测试·测试
han_hanker2 小时前
Java 对象序列化
java·开发语言
四代水门2 小时前
服务端倒带(Server-Side Rewind)命中判定系统
java·前端·算法
莫寒清2 小时前
@AliasFor 注解
java·spring
飞翔中文网2 小时前
Java学习笔记之接口
java·笔记·学习