SpringBoot 整合 Elasticsearch 实现海量级数据搜索

今天给大家讲讲 SpringBoot 框架 整合 Elasticsearch 实现海量级数据搜索 。
一、简介在上篇ElasticSearch 文章中 , 我们详细的介绍了 ElasticSearch 的各种 api 使用 。
实际的项目开发过程中 , 我们通常基于某些主流框架平台进行技术开发 , 比如 SpringBoot , 今天我们就以 SpringBoot 整合 ElasticSearch 为例 , 给大家详细的介绍 ElasticSearch 的使用!
SpringBoot 连接 ElasticSearch , 主流的方式有以下四种方式

  • 方式一:通过 Elastic Transport Client 客户端连接 es 服务器 , 底层基于 TCP 协议通过 transport 模块和远程 ES 服务端通信 , 不过 , 从 V7.0 开始官方不建议使用 , V8.0开始正式移除 。
  • 方式二:通过 Elastic JAVA Low Level Rest Client 客户端连接 es 服务器 , 底层基于 HTTP 协议通过 restful API 来和远程 ES 服务端通信 , 只提供了最简单最基本的 API , 类似于上篇文章中给大家介绍的 API 操作逻辑
  • Elastic Java High Level Rest Client Elastic Java Low Level Rest Client Elastic Transport Client
  • 方式四:通过 JestClient 客户端连接 es 服务器 , 这是开源社区基于 HTTP 协议开发的一款 es 客户端 , 官方宣称接口及代码设计比 ES 官方提供的 Rest 客户端更简洁、更合理 , 更好用 , 具有一定的 ES 服务端版本兼容性 , 但是更新速度不是很快 , 目前 ES 版本已经出到 V7.9 , 但是 JestClient 只支持 V1.0~V6.X 版 本的 ES 。
还有一个需要大家注意的地方 , 那就是版本号的兼容!
在开发过程中 , 大家尤其需要关注一下客户端和服务端的版本号 , 要尽可能保持一致 , 比如服务端 es 的版本号是 6.8.2  , 那么连接 es 的客户端版本号 , 最好也是 6.8.2  , 即使因项目的原因不能保持一致 , 客户端的版本号必须在 6.0.0 ~6.8.2  , 不要超过服务器的版本号 , 这样客户端才能保持正常工作 , 否则会出现很多意想不到的问题 , 假如客户端是 7.0.4 的版本号 , 此时的程序会各种报错 , 甚至没办法用!
为什么要这样做呢?主要原因就是 es 的服务端 , 高版本不兼容低版本;es6 和 es7 的某些 API 请求参数结构有着很大的区别 , 所以客户端和服务端版本号尽量保持一致 。
废话也不多说了 , 直接上代码!
二、代码实践本文采用的 SpringBoot 版本号是 2.1.0.RELEASE  , 服务端 es 的版本号是 6.8.2  , 客户端采用的是官方推荐的 Elastic Java High Level Rest Client 版本号是 6.4.2  , 方便与 SpringBoot 的版本兼容 。
2.1、导入依赖<!--elasticsearch--><dependency><groupId>org.elasticsearch</groupId><artifactId>elasticsearch</artifactId><version>6.4.2</version></dependency><dependency><groupId>org.elasticsearch.client</groupId><artifactId>elasticsearch-rest-client</artifactId><version>6.4.2</version></dependency><dependency><groupId>org.elasticsearch.client</groupId><artifactId>elasticsearch-rest-high-level-client</artifactId><version>6.4.2</version></dependency>2.2、配置环境变量在 Application.properties 全局配置文件中 , 配置 elasticsearch 自定义环境变量
elasticsearch.scheme=httpelasticsearch.address=127.0.0.1:9200elasticsearch.userName=elasticsearch.userPwd=elasticsearch.socketTimeout=5000elasticsearch.connectTimeout=5000elasticsearch.connectionRequestTimeout=50002.3、创建 elasticsearch 的 config 类@Configurationpublic class ElasticsearchConfiguration {private static final Logger log = LoggerFactory.getLogger(ElasticsearchConfiguration.class);private static final int ADDRESS_LENGTH = 2;@Value("${elasticsearch.scheme:http}")private String scheme;@Value("${elasticsearch.address}")private String address;@Value("${elasticsearch.userName}")private String userName;@Value("${elasticsearch.userPwd}")private String userPwd;@Value("${elasticsearch.socketTimeout:5000}")private Integer socketTimeout;@Value("${elasticsearch.connectTimeout:5000}")private Integer connectTimeout;@Value("${elasticsearch.connectionRequestTimeout:5000}")private Integer connectionRequestTimeout;/*** 初始化客户端* @return*/@Bean(name = "restHighLevelClient")public RestHighLevelClient restClientBuilder() {HttpHost[] hosts = Arrays.stream(address.split(",")).map(this::buildHttpHost).filter(Objects::nonNull).toArray(HttpHost[]::new);RestClientBuilder restClientBuilder = RestClient.builder(hosts);// 异步参数配置restClientBuilder.setHttpClientConfigCallback(httpClientBuilder -> {httpClientBuilder.setDefaultCredentialsProvider(buildCredentialsProvider());return httpClientBuilder;});// 异步连接延时配置restClientBuilder.setRequestConfigCallback(requestConfigBuilder -> {requestConfigBuilder.setConnectionRequestTimeout(connectionRequestTimeout);requestConfigBuilder.setSocketTimeout(socketTimeout);requestConfigBuilder.setConnectTimeout(connectTimeout);return requestConfigBuilder;});return new RestHighLevelClient(restClientBuilder);}/*** 根据配置创建HttpHost* @param s* @return*/private HttpHost buildHttpHost(String s) {String[] address = s.split(":");if (address.length == ADDRESS_LENGTH) {String ip = address[0];int port = Integer.parseInt(address[1]);return new HttpHost(ip, port, scheme);} else {return null;}}/*** 构建认证服务* @return*/private CredentialsProvider buildCredentialsProvider(){final CredentialsProvider credentialsProvider = new BasicCredentialsProvider();credentialsProvider.setCredentials(AuthScope.ANY, new UsernamePasswordCredentials(userName,userPwd));return credentialsProvider;}}


推荐阅读