Elasticsearch 8.x 集成与 Java API 使用指南

打印 上一主题 下一主题

主题 1015|帖子 1015|积分 3045

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?立即注册

x
目录
背景
版本区别
安装elaticsearch8.x服务
启动es服务
安装es管理平台
项目集成
pom.xml文件引入依靠
application.yml配置
ES初始化配置类实现
ES8.x常用API实现
1.判断es索引是否存在
2.删除索引
3.创建索引
4.新增文档
5.更新文档
6.根据id查询文档
7.根据id删除文档
8.查询文档列表
界说接口创建索引
界说业务方法
界说请求接口
操作接口


背景

随着 Elasticsearch 8.x 的发布,公司决定将现有的 Elasticsearch 7.x 版本升级到 8.x。然而,在升级过程中,我们发现许多 API 和功能发生了不兼容的厘革,导致系统在迁移过程中遇到了大量题目。固然官方文档提供了根本的操作指南,但实际应用中涉及的细节和调整却并未得到充实覆盖。为了帮助大家更顺利地过渡到 8.x,并有效应对这些厘革, 本文将具体探究 Elasticsearch 8.x 与 7.x 版本之间的主要差异,特殊是在 Java 开发中的实际应用与迁移题目。
版本区别

依靠差异


  • 版本7.x以及更早之前版本依靠
  1. <dependency>
  2.   <groupId>org.elasticsearch</groupId>
  3.   <artifactId>elasticsearch</artifactId>
  4.   <version>7.x.x</version>
  5. </dependency>
  6. <dependency>
  7.   <groupId>org.elasticsearch.client</groupId>
  8.   <artifactId>elasticsearch-rest-high-level-client</artifactId>
  9.   <version>7.x.x</version>
  10. </dependency>
复制代码


  • 8.x版本依靠
  1. <dependency>
  2.   <groupId>co.elastic.clients</groupId>
  3.   <artifactId>elasticsearch-java</artifactId>
  4.   <version>8.x.x</version>
  5. </dependency>
复制代码
安全性增强 :与 7.x 的默认无安全配置差别,8.x 默认启用安全功能,包括用户认证、授权、TLS 加密等,给开发者带来了更多的配置和管理任务。
查询和聚合优化:某些查询接口和聚合方法发生了厘革,特殊是对于大规模数据集的支持和性能提拔方面有了明显进步,但这些厘革需要开发者重新调整代码实现。
安装elaticsearch8.x服务

本文试例在window系统本地安装服务
启动es服务

elaticsearch版本为:8.16
   官方下载地址:Past Releases of Elastic Stack Software | Elastic
  百度云网盘:百度网盘 请输入提取码 提取码: 92h6
  下载完解压目录如下


进入config目录修改yml文件


因为8.x版本默认开启权限校验以及ssl证书校验,为了方便后续使用,这里只保留权限校验,关闭ssl证书校验


进入bin目录执行cmd打开命令行重置登录密码
.\elasticsearch-reset-password -u elastic
默认账号:elastic


   记得生存好密码,以免忘记
  进入bin目录双击elasticsearch.bat启动es服务




安装es管理平台


  • 可自行安装es官方面板:kibana
  • 本文使用的是google欣赏器插件:Multi Elasticsearch Heads(可在google插件市场下载)


打开插件并毗连es服务


毗连乐成


项目集成

这里通过集成在spring boot项目中来了解es8.x的配置毗连以及api的使用
注:固然基于springboot,但是我们这里不使用spring boot data提供的es集成依靠
  1. <dependency>
  2.   <groupId>org.springframework.boot</groupId>
  3.   <artifactId>spring-boot-starter-data-elasticsearch</artifactId>
  4.   <version>x.x.x</version>
  5. </dependency>
复制代码
  因为data只提供了一些es简朴操作的api,对于复杂的只有通过script手写DSL语句来完成,扩展性和维护性都不是很好,对不熟悉DSL语句的也很不友爱,以是我们照旧选择使用原生依靠 elasticsearch-java
  可下载博主github源码参考:GitHub - RemainderTime/spring-boot-base-demo: 拿来即用springboot基础框架项目
pom.xml文件引入依靠

  1. <!-- elasticsearch8.x 搜索引擎 -->
  2. <dependency>
  3.   <groupId>co.elastic.clients</groupId>
  4.   <artifactId>elasticsearch-java</artifactId>
  5.   <version>8.16.0</version>
  6. </dependency>
复制代码
application.yml配置

  1. elasticsearch:
  2.   host: localhost
  3.   port: 9200
  4.   username: elastic
  5.   password: 8wVPrsP=9vlQWHBuHniH  #window系统本地启动 es8.x 重置密码命令:.\elasticsearch-reset-password -u elastic
复制代码
ES初始化配置类实现

  1. @Component
  2. public class EsConfig {
  3.     @Value("${elasticsearch.host}")
  4.     private String elasticsearchHost;
  5.     @Value("${elasticsearch.port}")
  6.     private int elasticsearchPort;
  7.     @Value("${elasticsearch.username}")
  8.     private String username;
  9.     @Value("${elasticsearch.password}")
  10.     private String password;
  11.     /**
  12.      -最大连接数 (maxConnTotal):设置总的最大连接数,取决于业务的并发量。500-2000 之间较为合理。
  13.      -每个节点的最大连接数 (maxConnPerRoute):控制每个节点的最大连接数,建议 50-100 之间。
  14.      -IO 线程数 (setIoThreadCount):根据 CPU 核心数设置,通常为 2-4 倍 CPU 核心数。
  15.      -连接超时、套接字超时、获取连接超时:一般设置为 10-30 秒,复杂查询或大数据量操作可适当增加到 20-60 秒。
  16.      -失败监听器 (setFailureListener):自定义重试和故障处理逻辑,确保高可用性。
  17.      */
  18.     @Bean
  19.     public ElasticsearchClient elasticsearchClient() {
  20.         // 创建凭证提供者
  21.         CredentialsProvider credentialsProvider = new BasicCredentialsProvider();
  22.         credentialsProvider.setCredentials(
  23.             AuthScope.ANY,
  24.             new UsernamePasswordCredentials(username, password)
  25.         );
  26.         // 自定义 RestClientBuilder 配置
  27.         RestClientBuilder restClientBuilder = RestClient.builder(
  28.             new HttpHost(elasticsearchHost, elasticsearchPort, "http")
  29.         ).setHttpClientConfigCallback(httpClientBuilder ->
  30.                                       httpClientBuilder.setDefaultCredentialsProvider(credentialsProvider) // 配置认证信息
  31.                                      );
  32.         // 配置连接超时、套接字超时、获取连接超时
  33.         restClientBuilder.setRequestConfigCallback(builder ->
  34.                                                    builder.setConnectTimeout(20000)
  35.                                                    .setSocketTimeout(20000)
  36.                                                    .setConnectionRequestTimeout(20000)
  37.                                                   );
  38.         // 创建 RestClientTransport 和 ElasticsearchClient
  39.         RestClient restClient = restClientBuilder.build();
  40.         ElasticsearchTransport transport = new RestClientTransport(
  41.             restClient,
  42.             new JacksonJsonpMapper() // 使用 Jackson 进行 JSON 处理
  43.         );
  44.         return new ElasticsearchClient(transport);
  45.     }
  46. }
复制代码
ES8.x常用API实现

先创建一个全局es工具类
  1. @Slf4j
  2. @Component
  3. public class EsUtil {
  4.     public static ElasticsearchClient esClient;
  5.     {
  6.         esClient = (ElasticsearchClient) ApplicationContextUtils.getBean("elasticsearchClient");
  7.     }
  8.     /...
  9. }
复制代码
下面摆列工具类中实现的常用的操作方法。
1.判断es索引是否存在

  1. public static boolean existIndex(String indexName) {
  2.         try {
  3.             // 创建 ExistsRequest 请求
  4.             ExistsRequest request = new ExistsRequest.Builder()
  5.                     .index(indexName)
  6.                     .build();
  7.             // 发送请求并获取响应
  8.             BooleanResponse response = esClient.indices().exists(request);
  9.             // 返回索引是否存在
  10.             return response.value();
  11.         } catch (Exception e) {
  12.             // 处理异常
  13.             e.printStackTrace();
  14.             return false;
  15.         }
  16.     }
复制代码
2.删除索引

  1. @SneakyThrows
  2. public static void delIndex(String indexName) {
  3.     if (existIndex(indexName)) {
  4.         return;
  5.     }
  6.     esClient.indices().delete(d -> d.index(indexName));
  7. }
复制代码
3.创建索引

  1. public static void createIndex(String indexName) {
  2.     if (existIndex(indexName)) {
  3.         throw new RuntimeException("索引已经存在");
  4.     }
  5.     try {
  6.         CreateIndexResponse createIndexResponse = esClient.indices().create(c -> c.index(indexName));
  7.         // 处理响应
  8.         if (createIndexResponse.acknowledged()) {
  9.             log.info(" indexed create successfully.");
  10.         } else {
  11.             log.info("Failed to create index.");
  12.         }
  13.     } catch (Exception e) {
  14.         // 捕获异常并打印详细错误信息
  15.         e.printStackTrace();
  16.         throw new RuntimeException("创建索引失败,索引名:" + indexName + ",错误信息:" + e.getMessage(), e);
  17.     }
  18. }
复制代码
4.新增文档

  1. public static boolean addDocument(EsBaseModel esBaseModel) {
  2.     try {
  3.         // 创建 IndexRequest 实例
  4.         IndexRequest request = new IndexRequest.Builder()
  5.         .index(esBaseModel.getIndexName())
  6.         .id(esBaseModel.getDocumentId()) //指定文档id,不指定会自动生成
  7.         .document(esBaseModel.getDocumentModel())
  8.         .opType(OpType.Create) // 只会在文档 ID 不存在时创建文档
  9.         .build();
  10.    
  11.         IndexResponse response = esClient.index(request);
  12.         if ("created".equals(response.result())) {
  13.             log.info("Document created: " + response.id());
  14.             return true;
  15.         } else {
  16.             log.info("Document already exists or failed to create.");
  17.             return false;
  18.         }
  19.     } catch (Exception e) {
  20.         log.error("es新增文档失败", e);
  21.         e.printStackTrace();
  22.     }
  23.     return false;
  24. }
复制代码
5.更新文档

  1. public boolean updateDocument(EsBaseModel esBaseModel) {
  2.     try {
  3.         UpdateRequest updateRequest = new UpdateRequest.Builder<>()
  4.         .index(esBaseModel.getIndexName())
  5.         .id(esBaseModel.getDocumentId())
  6.         .doc(esBaseModel.getDocumentModel()).build();
  7.         UpdateResponse updateResponse = esClient.update(updateRequest, esBaseModel.getClazz());
  8.         log.info("Document updated: " + updateResponse.id());
  9.         return true;
  10.     } catch (Exception e) {
  11.         e.printStackTrace();
  12.     }
  13.     return false;
  14. }
复制代码
6.根据id查询文档

  1. public static <T> T getDocumentById(EsBaseModel esBaseModel) {
  2.     try {
  3.         GetRequest getRequest = new GetRequest.Builder()
  4.         .index(esBaseModel.getIndexName())
  5.         .id(esBaseModel.getDocumentId())
  6.         .build();
  7.         GetResponse<T> getResponse = esClient.get(getRequest, esBaseModel.getClazz());
  8.         if (getResponse.found()) {
  9.             return getResponse.source();
  10.         }
  11.     } catch (Exception e) {
  12.         log.error("es列表查询失败", e);
  13.     }
  14.     return null;
  15. }
复制代码
7.根据id删除文档

  1. public static Boolean deleteDocumentById(EsBaseModel esBaseModel) {
  2.     try {
  3.         DeleteRequest deleteRequest = new DeleteRequest.Builder()
  4.         .index(esBaseModel.getDocumentId())
  5.         .id(esBaseModel.getDocumentId())
  6.         .build();
  7.         DeleteResponse deleteResponse = esClient.delete(deleteRequest);
  8.         if ("deleted".equals(deleteResponse.result())) {
  9.             log.info("Document deleted: " + deleteResponse.id());
  10.             return true;
  11.         } else {
  12.             log.info("Document delete failed: " + deleteResponse.id());
  13.             return false;
  14.         }
  15.     } catch (Exception e) {
  16.         log.error("es列表删除失败", e);
  17.     }
  18.     return false;
  19. }
复制代码
8.查询文档列表

  1. public static <T> List<T> getDocumentList(EsSearchModel searchModel) {
  2.     List<T> eslist = new ArrayList<>();
  3.     try {
  4.         SearchResponse<T> search = esClient.search(buildSearchRequest(searchModel), searchModel.getClazz());
  5.         if (Objects.isNull(search)) {
  6.             return eslist;
  7.         }
  8.         HitsMetadata<T> hits = search.hits();
  9.         if (Objects.isNull(hits)) {
  10.             return eslist;
  11.         }
  12.         List<Hit<T>> sourceHitList = hits.hits();
  13.         if (CollectionUtils.isEmpty(sourceHitList)) {
  14.             return eslist;
  15.         }
  16.         sourceHitList.forEach(item -> {
  17.             // 处理每个命中
  18.             eslist.add(item.source());
  19.         });
  20.         return eslist;
  21.     } catch (Exception e) {
  22.         log.error("es列表查询失败", e);
  23.     }
  24.     return eslist;
  25. }
复制代码
  留意!!!由于方法太多,文中就不一一列举,想了解更多方法可下载上面博主提供的github地址进行下载项目并找到EsUtil.class类查看,内里有更多场景的使用方法和api详解
  界说接口创建索引

界说业务方法

  1. @Slf4j
  2. @Service
  3. public class UserServiceImpl implements UserService {
  4.     @Autowired
  5.     private UserMapper userMapper;
  6.     @Override
  7.     public RetObj syncEs(Long userId) {
  8.         User user = userMapper.selectById(userId);
  9.         if (Objects.isNull(user)) {
  10.             return RetObj.error("用户不存在");
  11.         }
  12.         String index = StringUtil.camelToKebabCase(user.getClass().getSimpleName());
  13.         if (!EsUtil.existIndex(index)) {
  14.             EsUtil.createIndex(index);
  15.         }
  16.         EsUtil.addDocument(new EsBaseModel(index, String.valueOf(user.getId()), user, user.getClass()));
  17.         return RetObj.success();
  18.     }
  19.     @Override
  20.     public RetObj getEsId(Long userId) {
  21.         Object user = EsUtil.getDocumentById(new EsBaseModel("user", String.valueOf(userId), null, User.class));
  22.         if(Objects.nonNull(user)){
  23.             return RetObj.success(user);
  24.         }
  25.         return RetObj.error("es中不存在该用户");
  26.     }
  27. }
复制代码
界说请求接口

  1. @RestController(value = "用户控制器")
  2. @RequestMapping("/user")
  3. @Tag(name = "用户控制器")
  4. public class UserController {
  5.     @Autowired
  6.     private UserService userService;
  7.     @Operation(summary = "es同步用户信息", description = "用户信息")
  8.     @GetMapping("/syncEs")
  9.     public RetObj syncEs(Long userId){
  10.         return userService.syncEs(userId);
  11.     }
  12.     @Operation(summary = "es查询用户信息", description = "用户信息")
  13.     @GetMapping("/getEsId")
  14.     public RetObj getEsId(Long userId){
  15.         return userService.getEsId(userId);
  16.     }
  17. }
复制代码
操作接口

请求接口插入一条数据到索引中


查看面板发现自动创建了一个user索引


查询user索引中的数据存在一条


请求接口查询es数据


至此对于Elaticsearch8.x版本的学习完成了


免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

民工心事

论坛元老
这个人很懒什么都没写!
快速回复 返回顶部 返回列表