当前位置: 首页 > news >正文

Elasticsearch基础篇-java程序通过RestClient操作es

目录

1.引入

2 初始化RestClient

1)引入es的RestHighLevelClient依赖:

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

3)初始化RestHighLevelClient:

4)测试

3.索引库操作

3.1.Mapping映射

3.1.1 举例

3.2 创建索引库

3.2.1 代码实现

3.3 删除索引库

3.3.1 代码实现

3.4 查询索引库

3.4.1 代码实现

3.5 总结

4. 文档操作

4.1 新增文档

4.2 删除文档

4.3 查询文档

4.4 修改文档

4.5 批量导入文档

4.5.1.语法说明

4.5.2 示例

4.6.小结


1.引入

之前我们介绍了如何在kibana的DevTools发送请求:

Kibana 的 Dev Tools 提供了一个方便的界面,可以执行 Elasticsearch 的各种 API 请求,如索引创建、文档操作

在数据量爆发式增长的今天,高效的搜索功能对于许多应用程序来说至关重要。Elasticsearch 作为一种强大的开源分布式搜索引擎,凭借其高性能、高扩展性和丰富的功能,被广泛应用于各种需要快速搜索和分析海量数据的场景。本文将介绍如何在 Java 程序中集成和使用 Elasticsearch,以实现高效的搜索功能,包括环境准备、代码示例以及一些实用的操作和技巧。

2 初始化RestClient

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

官方文档地址:

Elasticsearch clients | Elastic Docs

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

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

分为三步:

1)引入esRestHighLevelClient依赖:

<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)初始化RestHighLevelClient:

初始化的代码如下:

RestHighLevelClient client = new RestHighLevelClient(RestClient.builder(HttpHost.create("http://192.168.150.101:9200")  //docker部署es的服务器的地址
));

4)测试

为了单元测试方便,我们创建一个测试类IndexTest,然后将初始化的代码编写在@BeforeEach方法中:

public class IndexTest {private RestHighLevelClient client;@BeforeEachvoid setUp() {this.client = new RestHighLevelClient(RestClient.builder(HttpHost.create("http://192.168.150.101:9200")));}@Testvoid testConnect() {System.out.println(client);}@AfterEachvoid tearDown() throws IOException {this.client.close();}
}

3.索引库操作

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

3.1.Mapping映射

3.1.1 举例

对应的mapping映射属性如下:

字段名

字段类型

类型说明

是否

参与搜索

是否

参与分词

分词器

id

long

长整数

——

name

text

字符串,参与分词搜索

IK

price

integer

以分为单位,所以是整数

——

stock

integer

字符串,但需要分词

——

image

keyword

字符串,但是不分词

——

category

keyword

字符串,但是不分词

——

brand

keyword

字符串,但是不分词

——

sold

integer

销量,整数

——

commentCount

integer

评价,整数

——

isAD

boolean

布尔类型

——

updateTime

Date

更新时间

——

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

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"}}}
}

3.2 创建索引库

代码分为三步:

  • 1)创建Request对象。

    • 因为是创建索引库的操作,因此Request是CreateIndexRequest

  • 2)添加请求参数

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

  • 3)发送请求

    • client.indices()方法的返回值是IndicesClient类型,封装了所有与索引库操作有关的方法。例如创建索引、删除索引、判断索引是否存在等

3.2.1 代码实现

IndexTest测试类中,具体代码如下:

@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" +"}";

3.3 删除索引库

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

DELETE /hotel

与创建索引库相比:

  • 请求方式从PUT变为DELTE

  • 请求路径不变

  • 无请求参数

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

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

  • 2)准备参数。这里是无参,因此省略

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

3.3.1 代码实现

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

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

3.4 查询索引库

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

GET /hotel

因此与删除的Java代码流程是类似的,流程如下:

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

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

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

3.4.1 代码实现

@Test
void testExistsIndex() throws IOException {// 1.创建Request对象GetIndexRequest request = new GetIndexRequest("items");// 2.发送请求client.indices().get(request, RequestOptions.DEFAULT);
}

3.5 总结

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

索引库操作的基本步骤:

  • 初始化RestHighLevelClient

  • 创建XxxIndexRequest。XXX是CreateGetDelete

  • 准备请求参数( Create时需要,其它是无参,可以省略)

  • 发送请求。调用RestHighLevelClient#indices().xxx()方法,xxx是creategetdelete

4. 文档操作

4.1 新增文档

@Test
void testIndexDocument() throws IOException {
// 1.创建 request对象
// indexName:索引库名,1:设置文档id
IndexRequest request = new IndexRequest("indexName").id("1");
// 2.准备 JSON文档
request.source("{\"name\": \"Jack\", \"age\": 21}", XContentType.JSON);
// 3.发送请求
client.index(request, RequestOptions.DEFAULT);
}

4.2 删除文档

@Test
void testDeleteDocumentById() throws IOException {
// 1.创建 request对象
DeleteRequest request = new DeleteRequest("indexName", "1");
// 2.删除文档
client.delete(request, RequestOptions.DEFAULT);
}

4.3 查询文档

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

4.4 修改文档

修改我们讲过两种方式:

  • 全量修改:本质是先根据id删除,再新增

  • 局部修改:修改文档中的指定字段值

在RestClient的API中,全量修改与新增的API完全一致,判断依据是ID:

  • 如果新增时,ID已经存在,则修改

  • 如果新增时,ID不存在,则新增

这里不再赘述,我们主要关注局部修改的API即可。

@Test
void testUpdateDocument() throws IOException {// 1.准备RequestUpdateRequest request = new UpdateRequest("items", "100002644680");//索引库,文档id// 2.准备请求参数request.doc("price", 58800,"commentCount", 1);// 3.发送请求client.update(request, RequestOptions.DEFAULT);
}

4.5 批量导入文档

在之前的案例中,我们都是操作单个文档。而数据库中的商品数据实际会达到数十万条,某些项目中可能达到数百万条。

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

  • 利用Logstash批量导入

    • 需要安装Logstash

    • 对数据的再加工能力较弱

    • 无需编码,但要学习编写Logstash导入配置

  • 利用JavaAPI批量导入

    • 需要编码,但基于JavaAPI,学习成本低

    • 更加灵活,可以任意对数据做再加工处理后写入索引库

接下来,我们就学习下如何利用JavaAPI实现批量文档导入。

4.5.1.语法说明

批处理与前面讲的文档的CRUD步骤基本一致:

  • 创建Request,但这次用的是BulkRequest

  • 准备请求参数

  • 发送请求,这次要用到client.bulk()方法

BulkRequest本身其实并没有请求参数,其本质就是将多个普通的CRUD请求组合在一起发送。例如:

  • 批量新增文档,就是给每个文档创建一个IndexRequest请求,然后封装到BulkRequest中,一起发出。

  • 批量删除,就是创建N个DeleteRequest请求,然后封装到BulkRequest,一起发出

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

能添加的请求有:

  • IndexRequest,也就是新增

  • UpdateRequest,也就是修改

  • DeleteRequest,也就是删除

因此Bulk中添加了多个IndexRequest,就是批量新增功能了。

4.5.2 示例

@Test
void testBulk() throws IOException {// 1.创建RequestBulkRequest 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);
}

4.6.小结

文档操作的基本步骤:

  • 初始化RestHighLevelClient

  • 创建XxxRequest。

    • XXX是IndexGetUpdateDeleteBulk

  • 准备参数(IndexUpdateBulk时需要)

  • 发送请求。

    • 调用RestHighLevelClient#.xxx()方法,xxx是indexgetupdatedeletebulk

  • 解析结果(Get时需要)

相关文章:

  • BUUCTF——ReadlezPHP
  • Android 手写签名功能详解:从原理到实践
  • 第五部分:阶段项目 4:构建 RESTful API 服务器
  • 关于机器学习的实际案例
  • 【Java ee初阶】jvm(2)
  • 股票数据源对接技术指南:印度尼西亚、印度、韩国
  • ubuntu22.04搭建ROS2环境
  • C++_数据结构_哈希表(hash)实现
  • 阶段四 项目1-苍穹外卖 第一章 Git
  • 论文学习:《引入TEC - LncMir,通过对RNA序列的深度学习来预测lncRNA - miRNA的相互作用》
  • Java面试深度解析:微服务与云原生技术应用场景详解
  • 菜鸟之路Day32一一多表查询,事物,索引
  • Ubuntu 20.04 报错记录: Matplotlib 无法使用 OpenCV 的 libqxcb.so
  • 76.有符号数累加运算
  • 从坏道扫描到错误修复:HD Tune实战指南
  • 小白到高手的人工智能学习笔记之初步了解pytorch
  • Ubuntu24.04下安装ISPConfig全过程记录
  • AM32电调学习解读八:无感驱动相位波形解析
  • 架构思维:构建高并发扣减服务_分布式无主架构
  • SQL性能分析
  • 体坛联播|雷霆抢七淘汰掘金,国米错失意甲登顶良机
  • 俄乌刚谈完美国便筹划与俄乌领导人通话,目的几何?
  • 气急败坏!20多名台湾艺人被台当局列为“重点核查对象”
  • 广西壮族自治区党委常委会:坚决拥护党中央对蓝天立进行审查调查的决定
  • 探秘多维魅力,长江经济带、珠三角媒体总编辑岳阳行启动
  • 中国社联成立95周年,《中国社联期刊汇编》等研究丛书出版