一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第2天,点击查看活动详情。
前言
上篇文章说要集成elasticsearch8.x版本,今天把遇到的坑和集成步骤发一下供大家参考。本文主要参考的文章见:点击查看整合的参考地址,点击查看参考的官方文档
step1:安装elasticsearch8.1.2
这里说一下,我安装的是最新版本的es(截止到2022年4月2日),并且在maven仓库里可以找到对应版本的连接器,大家可以在整合的时候按照最新的版本进行整合。
- 下载es8.1.2 可以访问这个地址,下载的更快一些加速地址,点击download之后我下载的版本是8.1.2
- 解压
- 修改配置文件 es8.1.2默认使用了xpack进行加密,所以我们先改一下配置文件,先用不加密的方式进行本地demo开发。先找到解压出来文件目录下的config目录,找到elasticsearch.yml文件,我们直接覆盖为以下内容
cluster.name: my-es
xpack.security.enabled: false
xpack.security.enrollment.enabled: false
xpack.security.http.ssl:
enabled: false
keystore.path: certs/http.p12
xpack.security.transport.ssl:
enabled: false
verification_mode: certificate
keystore.path: certs/transport.p12
truststore.path: certs/transport.p12
cluster.initial_master_nodes: ["WIN-O8STQHDPFBA"]
http.host: [_local_, _site_]
这里我们主要是配置了节点名称和禁用xpack加密
- 跳转到bin目录下,双击elasticsearch.bat就可以在Windows上启动es了,启动完成后我们访问127.0.0.1:9200,出现下面的信息代表启动成功了
{
"name" : "WIN-O8STQHDPFBA",
"cluster_name" : "my-es",
"cluster_uuid" : "ph9V_VxtR4u0Qk92UlxCAw",
"version" : {
"number" : "8.1.2",
"build_flavor" : "default",
"build_type" : "zip",
"build_hash" : "31df9689e80bad366ac20176aa7f2371ea5eb4c1",
"build_date" : "2022-03-29T21:18:59.991429448Z",
"build_snapshot" : false,
"lucene_version" : "9.0.0",
"minimum_wire_compatibility_version" : "7.17.0",
"minimum_index_compatibility_version" : "7.0.0"
},
"tagline" : "You Know, for Search"
}
step2:整合es8.1.2至spring boot
- 从spring.start.io初始化一个spring boot的项目。我初始化的版本为 2.6.5,这里只需要spring boot start启动即可,下一步我们引入必须的依赖
- 在pom.xml中添加完所需的依赖后完整的依赖如下
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.13.2</version>
</dependency>
<dependency>
<groupId>org.glassfish</groupId>
<artifactId>jakarta.json</artifactId>
<version>2.0.1</version>
</dependency>
<dependency>
<groupId>co.elastic.clients</groupId>
<artifactId>elasticsearch-java</artifactId>
<version>8.1.2</version>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>3.12.0</version>
</dependency>
</dependencies>
- 在application.yml中添加配置,内容如下
spring:
elasticsearch:
uris: 127.0.0.1:9200
server:
port: 4001
logging:
level:
root: debug
这里我们指定es的uri服务的端口和打印日志为debug
- 统一的clientBean 我们定义一个统一的bean用来处理统一的client。在config文件夹下创建文件内容如下:
package code.liang.top.config;
import co.elastic.clients.elasticsearch.ElasticsearchClient;
import co.elastic.clients.json.jackson.JacksonJsonpMapper;
import co.elastic.clients.transport.ElasticsearchTransport;
import co.elastic.clients.transport.rest_client.RestClientTransport;
import org.apache.commons.lang3.StringUtils;
import org.apache.http.HttpHost;
import org.elasticsearch.client.RestClient;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import java.util.Arrays;
/**
* es config
*
* @author lmh
*/
@Configuration
public class ElasticSearchConfig {
@Value("${spring.elasticsearch.uris}")
private String elasticsearchUris;
@Bean
public ElasticsearchClient elasticsearchClient() {
if (StringUtils.isNoneBlank(elasticsearchUris)) {
RestClient client = RestClient.builder(Arrays.stream(elasticsearchUris.split(",")).map(HttpHost::create).toArray(HttpHost[]::new)).build();
ElasticsearchTransport transport = new RestClientTransport(client, new JacksonJsonpMapper());
return new ElasticsearchClient(transport);
} else {
throw new RuntimeException("未读取到es的uri配置信息");
}
}
}
这里我们同时支持了多个esclient集群连接
step3:常用api和原理
我们在第二步已经定义好了一个client bean,下面我简单介绍一下实现的原理
index索引相关原理
话不多说,先上代码
package code.liang.top.modules.controller;
import co.elastic.clients.elasticsearch.ElasticsearchClient;
import co.elastic.clients.elasticsearch.indices.*;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.io.IOException;
/**
* @author lmh
*/
@Slf4j
@RestController
@RequestMapping("es/index")
@RequiredArgsConstructor
public class EsIndexController {
private final ElasticsearchClient elasticsearchClient;
@GetMapping("createIndex")
public String createIndex() throws IOException {
CreateIndexResponse createResponse = elasticsearchClient.indices().create(demo -> demo.index("demo1"));
return Boolean.TRUE.equals(createResponse.acknowledged()) ? "创建成功" : "创建失败";
}
@GetMapping("searchIndexList")
public String searchIndexList() throws IOException {
GetIndexResponse getIndexResponse = elasticsearchClient.indices().get(demo -> demo.index("*"));
return String.join(",", getIndexResponse.result().keySet());
}
@GetMapping("deleteIndex")
public String deleteIndex() throws IOException {
DeleteIndexResponse deleteIndexResponse = elasticsearchClient.indices().delete(demo -> demo.index("demo1"));
return Boolean.TRUE.equals(deleteIndexResponse.acknowledged()) ? "删除成功" : "删除失败";
}
}
- createIndex 示例相当于使用put请求调用es的这个接口 ip:9200/first_demo_index,请求体为:
{
"settings": {
"number_of_shards": 1,
"number_of_replicas": 0
}
}
- createIndex 示例相当于使用get请求调用es的这个接口 ip:9200/*
- deleteIndex 示例相当于使用delete请求调用es的这个接口 ip:9200/first_demo_index
documen相关示例
package code.liang.top.modules.controller;
import cn.hutool.core.util.RandomUtil;
import co.elastic.clients.elasticsearch.ElasticsearchClient;
import co.elastic.clients.elasticsearch.core.GetResponse;
import co.elastic.clients.elasticsearch.core.IndexResponse;
import co.elastic.clients.elasticsearch.core.SearchRequest;
import co.elastic.clients.elasticsearch.core.SearchResponse;
import co.elastic.clients.elasticsearch.core.search.Hit;
import co.elastic.clients.transport.endpoints.BooleanResponse;
import code.liang.top.modules.entity.SysUserEs;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
/**
* @author lmh
*/
@Slf4j
@RestController
@RequestMapping("es/demo")
@RequiredArgsConstructor
public class EsDemoController {
private final ElasticsearchClient elasticsearchClient;
@GetMapping("initIndexAndInsert")
public String initIndexAndInsert() throws IOException {
BooleanResponse booleanResponse = elasticsearchClient.indices().exists(demo1 -> demo1.index("demo1"));
if (booleanResponse.value()) {
elasticsearchClient.indices().delete(demo1 -> demo1.index("demo1"));
}
IndexResponse indexResponse = elasticsearchClient.index(demo1 -> demo1.index("demo1").id("123456").document(new SysUserEs().setAge(18).setBalance(100.00).setEnabled(true).setName("hello world")));
return indexResponse.result().jsonValue();
}
@GetMapping("insert")
public String insert() throws IOException {
IndexResponse indexResponse = elasticsearchClient.index(demo1 -> demo1.index("demo1").id(System.currentTimeMillis() + "" + RandomUtil.randomString(6)).document(new SysUserEs().setAge(18).setBalance(100.00).setEnabled(true).setName("hello world")));
return indexResponse.result().jsonValue();
}
@GetMapping("search")
public String search() throws IOException {
GetResponse<SysUserEs> getResponse = elasticsearchClient.get(demo1 -> demo1.index("demo1").id("123456"), SysUserEs.class);
return getResponse.source().toString();
}
@GetMapping("list")
public String list() throws IOException {
SearchRequest searchRequest = new SearchRequest.Builder().build();
SearchResponse<SysUserEs> getResponse = elasticsearchClient.search(searchRequest, SysUserEs.class);
List<String> strList = new ArrayList<>();
getResponse.hits().hits().stream().forEach(item -> {
strList.add(item.source().toString());
});
return String.join(",", strList);
}
}
底层原理暂不赘述了,大家可以下载代码本地运行然后看控制台的请求体就可以了
结语
今天整合了spring boot 2.6.5+es8.1.2,以后有时间看一下ik分词器,然后自己写一些注解在程序启动的时候基于aop创建索引。所有的代码在gitee上都可以看到,地址四月更文后端地址,大家可以自己下载试运行
- 明天预告:
- nodejs+react+taro开发多端可运行的代码(uni-app其实会vue就不是很难,大家有兴趣我也写一版vue的)
- es8.1.2 ik分词关键词匹配查询,这个计划使用docker安装es 上面两个方向我今晚想一下要开发那个吧。还请大家期待一下明天的文章!