SpringBoot - Elasticsearch Rest Client使用详解1(安装配置、索引的增删改查)
一、准备工作
1,关于 Elasticsearch Rest Client
(1)目前 Elasticsearch 提供了两个 Java REST Client 版本:Java Low Level REST Client 和 Java High Level REST Client。它们均封装了 ES 操作,二者的区别如下:
- Java Low Level REST Client:低级别的 REST 客户端,通过 HTTP 与集群交互,用户需自己组装请求 JSON 串和解析响应 JSON 串,兼容所有 Elasticsearch 版本。
- Java High Level REST Client:高级别的 REST 客户端,基于低级别的 REST 客户端进行了封装,增加了组装请求 JSON 串、解析响应 JSON 串等相关 API。开发代码使用的 Elasticsearch 版本需要和集群中的 Elasticsearch 版本一致,否则会有版本冲突问题。
(2)二者的使用建议如下:
- 如果考虑到代码后期的兼容性,则建议使用 Java Low Level REST Client。
- 如果考虑到易用性,则建议使用 Java High Level REST Client。Java High Level REST Client 这种方式是从 Elasticsearch 6.0 版本开始加入的,目的是以 Java 面向对象的方式请求/响应处理。
注意:Java High Level REST Client 会兼容高版本的 Elasticsearch 集群,例如:使用 Elasticsearch 7.0 版本开发的代码,可以和任何 7.x 版本的 Elasticsearch 集群交互。
如果 Elasticsearch 集群后期升级到了 8.x 版本,则也要升级之前基于 Elasticsearch 7.0 版本开发的代码。
2,项目配置
(1)这里我们使用 Java High Level REST Client 对 Elasticsearch 进行操作,首先在项目的 pom.xml 文件中,添加 Elasticsearch 的依赖和日志的依赖。
<dependency> <groupId>org.elasticsearch.client</groupId> <artifactId>elasticsearch-rest-high-level-client</artifactId> <version>7.6.0</version> </dependency> <dependency> <groupId>org.apache.logging.log4j</groupId> <artifactId>log4j-core</artifactId> <version>2.14.1</version> </dependency>
(2)接着在项目的 resources 目录下添加 log4j2.properties,内容如下:
appender.console.type = Console appender.console.name = console appender.console.layout.type = PatternLayout appender.console.layout.pattern = [%d{ISO8601}][%-5p][%-25c] $marker%m%n rootLogger.level = info rootLogger.appenderRef.console.ref = console
二、索引库的操作样例
1,创建索引库
下面代码创建一个名为 test 的索引库,分片数为 3:
// 获取 RestClient 连接 RestHighLevelClient client = new RestHighLevelClient(RestClient.builder( new HttpHost("192.168.60.9", 9200, "http"), new HttpHost("192.168.60.10", 9200, "http"), new HttpHost("192.168.60.11", 9200, "http"))); // 创建索引请求 CreateIndexRequest createRequest = new CreateIndexRequest("test"); // 指定索引库的配置信息(分片个数为 3) createRequest.settings(Settings.builder().put("index.number_of_shards", 3)); // 执行 client.indices().create(createRequest, RequestOptions.DEFAULT); // 关闭连接 client.close();
2,删除索引库
下面命令删除 test 这个索引库:
// 获取 RestClient 连接 RestHighLevelClient client = new RestHighLevelClient(RestClient.builder( new HttpHost("192.168.60.9", 9200, "http"), new HttpHost("192.168.60.10", 9200, "http"), new HttpHost("192.168.60.11", 9200, "http"))); // 删除索引库请求 DeleteIndexRequest deleteRequest = new DeleteIndexRequest("test"); // 执行 client.indices().delete(deleteRequest, RequestOptions.DEFAULT); // 关闭连接 client.close();
三、索引的操作样例
1,添加索引
(1)下面命令在 emp 索引库中添加一条 id 为 1 的索引,同时使用 HashMap 作为索引文档数据的源数据:
// 获取 RestClient 连接 RestHighLevelClient client = new RestHighLevelClient(RestClient.builder( new HttpHost("192.168.60.9", 9200, "http"), new HttpHost("192.168.60.10", 9200, "http"), new HttpHost("192.168.60.11", 9200, "http"))); // 创建索引请求 IndexRequest request = new IndexRequest("emp"); // 设置文档的唯一标识符为"1" request.id("1"); // 创建一个 HashMap,存储文档的字段和对应的值 HashMap<String, Object> jsonMap = new HashMap<>(); jsonMap.put("name", "hangge"); jsonMap.put("age", 20); // 将 HashMap 作为文档的源数据 request.source(jsonMap); // 执行索引操作,将文档添加到名为"emp"的索引中 client.index(request, RequestOptions.DEFAULT); // 关闭连接 client.close();
(2)下面命令在 emp 索引库中添加一条 id 为 2 的索引,这次使用 JSON 字符串作为索引文档数据的源数据:
// 获取 RestClient 连接 RestHighLevelClient client = new RestHighLevelClient(RestClient.builder( new HttpHost("192.168.60.9", 9200, "http"), new HttpHost("192.168.60.10", 9200, "http"), new HttpHost("192.168.60.11", 9200, "http"))); // 创建索引请求 IndexRequest request = new IndexRequest("emp"); // 设置文档的唯一标识符为"2" request.id("2"); // 构造 JSON 字符串表示文档的内容 String jsonString ="{" + "\"name\":\"baidu\"," + "\"age\":99" + "}"; // 将 JSON 字符串作为文档的源数据,设置文档的内容 request.source(jsonString, XContentType.JSON); // 执行索引操作,将文档添加到名为"emp"的索引中 client.index(request, RequestOptions.DEFAULT); // 关闭连接 client.close();
2,查询索引
(1)下面代码查询指定索引名称为“emp”,文档唯一标识符为“1”的数据:
// 获取 RestClient 连接 RestHighLevelClient client = new RestHighLevelClient(RestClient.builder( new HttpHost("192.168.60.9", 9200, "http"), new HttpHost("192.168.60.10", 9200, "http"), new HttpHost("192.168.60.11", 9200, "http"))); // 创建获取请求,指定索引名称为"emp",文档唯一标识符为"1" GetRequest request = new GetRequest("emp", "1"); // 执行获取操作,通过 response 获取 index、id、文档详细内容(ource) GetResponse response = client.get(request, RequestOptions.DEFAULT); // 获取索引名称和文档唯一标识符 String index = response.getIndex(); String id = response.getId(); // 如果查询到文档数据,则 isExists 返回 true if (response.isExists()) { System.out.println("--- 获取 JSON 字符串格式的文档结果 ---"); String sourceAsString = response.getSourceAsString(); System.out.println(sourceAsString); System.out.println("--- 获取 MAP 格式的文档结果 ---"); Map<String, Object> sourceAsMap = response.getSourceAsMap(); System.out.println(sourceAsMap); } else { // 如果没有查询到文档数据,则输出警告信息 System.out.println("没有查询到索引库 " + index + " 中 id 为 " + id + " 的文档!"); } // 关闭与 Elasticsearch 集群的连接,释放资源 client.close();
(2)查询时可以指定只获取部分字段或者排除部分字段的内容,下面代码只查询 name 这个字段数据:
// 获取 RestClient 连接 RestHighLevelClient client = new RestHighLevelClient(RestClient.builder( new HttpHost("192.168.60.9", 9200, "http"), new HttpHost("192.168.60.10", 9200, "http"), new HttpHost("192.168.60.11", 9200, "http"))); // 创建获取请求,指定索引名称为"emp",文档唯一标识符为"1" GetRequest request = new GetRequest("emp", "1"); // 只查询部分字段 String[] includes =new String[] {"name"}; // 指定包含哪些字段 String[] excludes = Strings.EMPTY_ARRAY; // 指定过滤哪些字段 FetchSourceContext fetchSourceContext = new FetchSourceContext(true, includes, excludes); request.fetchSourceContext(fetchSourceContext); // 执行获取操作,通过 response 获取 index、id、文档详细内容(ource) GetResponse response = client.get(request, RequestOptions.DEFAULT); // 获取索引名称和文档唯一标识符 String index = response.getIndex(); String id = response.getId(); // 如果查询到文档数据,则 isExists 返回 true if (response.isExists()) { System.out.println("--- 获取 JSON 字符串格式的文档结果 ---"); String sourceAsString = response.getSourceAsString(); System.out.println(sourceAsString); System.out.println("--- 获取 MAP 格式的文档结果 ---"); Map<String, Object> sourceAsMap = response.getSourceAsMap(); System.out.println(sourceAsMap); } else { // 如果没有查询到文档数据,则输出警告信息 System.out.println("没有查询到索引库 " + index + " 中 id 为 " + id + " 的文档!"); } // 关闭与 Elasticsearch 集群的连接,释放资源 client.close();
3,更新索引
(1)新索引可以分为全部更新和局部更新。全部更新同添加索引。如果指定 ID 的索引数据(文档)已经存在,则执行更新操作。
提示:在执行更新操作时,Elasticsearch 首先将旧的文标识为删除状态,然后添加新的文档。旧的文档不会立即消失,但是你也无法访问,Elasticsearch 会在你继续添加更多文档时在后台清理掉已经被标识为删除状态的文档。
// 获取 RestClient 连接 RestHighLevelClient client = new RestHighLevelClient(RestClient.builder( new HttpHost("192.168.60.9", 9200, "http"), new HttpHost("192.168.60.10", 9200, "http"), new HttpHost("192.168.60.11", 9200, "http"))); // 创建更新请求,指定索引为"emp",文档 ID 为"1" UpdateRequest request = new UpdateRequest("emp", "1"); // 定义要更新的文档字段信息,这里示例为设置年龄为 88 String jsonString = "{\"age\":88}"; request.doc(jsonString, XContentType.JSON); // 执行更新操作 client.update(request, RequestOptions.DEFAULT); // 关闭与 Elasticsearch 集群的连接,释放资源 client.close();
4,删除索引
下面代码删除 id=1 的索引数据:
// 获取 RestClient 连接 RestHighLevelClient client = new RestHighLevelClient(RestClient.builder( new HttpHost("192.168.60.9", 9200, "http"), new HttpHost("192.168.60.10", 9200, "http"), new HttpHost("192.168.60.11", 9200, "http"))); // 创建删除请求,指定索引为"emp",文档 ID 为"1" DeleteRequest request =new DeleteRequest("emp","1"); // 执行删除操作 client.delete(request, RequestOptions.DEFAULT); // 关闭与 Elasticsearch 集群的连接,释放资源 client.close();