目录
前言
本篇使用的elasticsearch版本为8.13.4,jdk版本为17,单机版的elasticsearch
最近做了个需求是文章查重的,使用了向量数据库搭配elasticsearch做了这个需求,由于甲方比较追求新的东西,所以不得已使用了8.13.4的版本,做个记录方便以后参考
安装Elasticsearch
若已经安装了elasticsearch 8 版本的可直接跳过
1、前往elasticsearch官网下载对应版本
Download Elasticsearch | Elastic
由于我本机使用的是arm版本的linux,这里我下载的版本是aarch64版本的,可以使用uname -m查看对应需要下载的版本
uname -m
将下载的elasticsearch上传到服务器,使用scp命令
scp -r 上传文件的本机路径 服务器登陆账号@服务器地址:上传到服务器的路径
例如:
scp -r ~/Downloads/elasticsearch-8.13.4-linux-aarch64.tar.gz root@10.211.55.3:/opt/elasticsearch-8.13.4-linux-aarch64.tar.gz
解压elastcisearch
tar -zxvf elasticsearch-8.13.4-linux-aarch64.tar.gz
将elasticserach移动到/usr/local目录 ,如果你就是想放在你上传的服务器目录可以忽略
mv elasticsearch-8.13.4 /usr/local/elasticsearch-8.13.4
cd /usr/local
由于elasticsearch 8.13.4 默认不支持root用户启动,这里创建 一个es用户,当然你也可以编辑es启动文件来设置支持root用户启动
groupadd es
useradd es
chown es:es -R /usr/local/elasticsearch-8.13.4
使用es用户启动,进入es目录中的bin目录,执行./elasticsearch,后台启动使用./elasticsearch -d
./elasticsearch -d
启动完控制台会输出后面需要使用的参数
可以看到生成了用户密码:elastic的密码为:*+mtSPJUQceM91o5000j
还有http ca certificate 这块是证书的内容,这里我使用的是apikey的方式去连接,你如果需要可以自行了解
还有kibana的token
验证是否安装成功
浏览器输入https://ip地址:9200,例如我的ip地址是:10.211.55.3 输入用户密码
https://10.211.55.3:9200/
安装ik中文分词器,进入elsaticsearch目录
cd /usr/local/elasticsearch-8.13.4/
bin/elasticsearch-plugin install https://get.infini.cloud/elasticsearch/analysis-ik/8.13.4
当然你也可以使用本地安装的方式去安装,下载ik分词器对应版本
上传到服务器后使用file://文件zip包地址去安装:例如
cd /usr/local/elasticsearch-8.13.4/
bin/elasticsearch-plugin install file:///opt/elasticsearch-analysis-ik-8.13.4.zip
重启elasticsearch
安装Kibana
若安装了kibana或其他可视化工具的可直接跳过
下载对应elasticsearch版本的kibana,一样的使用uname -m 查看主机的硬件架构,我使用的是arm版本
Download Kibana Free | Get Started Now | Elastic
使用scp上传,这里的scp使用方式可以去安装 elasticsearch 的内容查看
scp -r ~/Downloads/kibana-8.13.4-linux-aarch64.tar.gz root@10.211.55.3:/opt/kibana-8.13.4-linux-aarch64.tar.gz
解压kibana
tar -zxvf kibana-8.13.4-linux-aarch64.tar.gz
mv kibana-8.13.4 /usr/local/kibana-8.13.4
cd /usr/local/kibana-8.13.4
编辑config文件配置host
vim config/kibana.yml
修改server.host为你的ip地址,例如我的ip地址为:10.211.55.3
kibana默认不支持root用户启动,可以创建kibana用户,同安装 elasticsearch内容 中的创建es用户一样,这里为了方便直接使用root用户启动,可以自行去安装elasticsearch内容中查看如何创建用户和授权用户目录权限
./kibana --allow-root
查看控制台输出获取code,如图
浏览器输入对应控制台输出的地址: http://10.211.55.3:5601/?code=288638
控制台获取生成kibana用户的token,进入elastisearch目录
bin/elasticsearch-create-enrollment-token --scope kibana
浏览器输入token
登录elastic用户,生产apikey,如图
保存apiKey
项目添加依赖
前面环境准备完毕,现在添加项目依赖,本篇使用的是Gradle,当然这只是依赖管理的方式,你也可以使用maven
Gradle添加依赖
implementation 'co.elastic.clients:elasticsearch-java:8.13.4'
Maven添加依赖
<dependency>
<groupId>co.elastic.clients</groupId>
<artifactId>elasticsearch-java</artifactId>
<version>8.13.4</version>
</dependency>
这里还使用hutool工具包
Gradle
implementation 'cn.hutool:hutool-all:5.8.27'
Maven
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
<version>5.8.27</version>
</dependency>
编写 ElasticsearchConfiguration
@Configuration
public class ElasticsearchConfiguration {
@Value("${elasticsearch.url}")
private String url;
@Value("${elasticsearch.apiKey}")
private String apiKey;
@Bean
public ElasticsearchClient elasticsearchClient() {
RestClientBuilder builder = RestClient.builder(HttpHost.create(url));
// ignore ssl context
this.ignoreSSLContext(builder);
builder.setDefaultHeaders(new Header[]{
new BasicHeader("Authorization", "ApiKey " + apiKey)
});
RestClient restClient = builder.build();
ElasticsearchTransport transport = new RestClientTransport(restClient, new JacksonJsonpMapper());
return new ElasticsearchClient(transport);
}
private void ignoreSSLContext(RestClientBuilder builder) {
builder.setHttpClientConfigCallback(localeResolver -> {
try {
SSLContext sslContext = SSLContext.getInstance("TLS");
sslContext.init(null, new TrustManager[]{
new X509TrustManager() {
@Override
public void checkClientTrusted(X509Certificate[] x509Certificates, String s) throws CertificateException {
}
@Override
public void checkServerTrusted(X509Certificate[] x509Certificates, String s) throws CertificateException {
}
@Override
public X509Certificate[] getAcceptedIssuers() {
return new X509Certificate[0];
}
}
}, null);
return localeResolver.setSSLContext(sslContext);
} catch (Exception e) {
throw new RuntimeException(e);
}
});
}
}
工具类编写
编写ElasticsearchUtil
@Slf4j
public class ElasticsearchUtil {
public static ElasticsearchClient elasticsearchClient;
static {
elasticsearchClient = SpringUtil.getBean(ElasticsearchClient.class);
}
/**
* elasticsearch index exists
*
* @param indexName index name
* @return true/false
*/
public static boolean indexExists(String indexName) {
try {
return elasticsearchClient.indices().exists(e -> e.index(indexName)).value();
} catch (Exception e) {
log.error("indexExists error", e);
}
return false;
}
/**
* create elasticsearch index
*
* @param indexName index name
* @param configureJson create index configure json
* @return true/false
*/
public static boolean createIndex(String indexName, String configureJson) throws IOException {
try {
boolean exists = indexExists(indexName);
if (exists) {
log.debug("create index {} is already exist", indexName);
return true;
}
if (StringUtils.hasText(configureJson)) {
elasticsearchClient.indices().create(e -> e.index(indexName).withJson(new StringReader(configureJson)));
log.debug("create index {} success", indexName);
return true;
}
elasticsearchClient.indices().create(e -> e.index(indexName));
log.debug("create index {} success", indexName);
return true;
} catch (Exception e) {
log.error("create index error", e);
}
return false;
}
/**
* delete elasticsearch index
*
* @param indexName index name
* @return true/false
*/
public static boolean deleteIndex(String indexName) {
try {
boolean exists = indexExists(indexName);
if (!exists) {
log.debug("delete index {} is no exist", indexName);
return true;
}
elasticsearchClient.indices().delete(e -> e.index(indexName));
return true;
} catch (Exception e) {
log.error("delete index error", e);
}
return false;
}
/**
* delete elasticsearch index
*
* @param indexName index name
* @param id id
* @return true/false
*/
public static boolean deleteIndex(String indexName, String id) {
try {
boolean exists = indexExists(indexName);
if (!exists) {
log.debug("delete index index is no exist indexName {} id {}", indexName, id);
return true;
}
exists = elasticsearchClient.exists(e -> e.index(indexName).id(id)).value();
if (!exists) {
log.debug("delete index {} id {} is no exist", indexName, id);
return true;
}
elasticsearchClient.delete(e -> e.index(indexName).id(id));
return true;
} catch (Exception e) {
log.error("delete index error", e);
}
return false;
}
/**
* add elasticsearch index doc
*
* @param indexName index name
* @param id id
* @param doc doc
* @param clazz doc class
* @param <T> doc class obj
* @return true/false
*/
public static <T> boolean addDocument(String indexName, String id, T doc, Class<T> clazz) {
try {
boolean exists = indexExists(indexName);
if (!exists) {
log.debug("add document index {} is no exist indexName {} id {}", indexName, id, doc);
return false;
}
exists = elasticsearchClient.exists(e -> e.index(indexName).id(id)).value();
if (exists) {
elasticsearchClient.update(update -> update.index(indexName).id(id).doc(doc), clazz);
return true;
}
elasticsearchClient.index(index -> index.index(indexName).id(id).document(doc));
return true;
} catch (Exception e) {
log.error("add document error", e);
}
return false;
}
/**
* get elasticsearch index doc
*
* @param request search request
* @param clazz result class
* @param <T> result class obj
* @return doc
*/
public static <T> SearchResponse<T> getDocument(SearchRequest request, Class<T> clazz) {
try {
return elasticsearchClient.search(request, clazz);
} catch (Exception e) {
log.error("get document error", e);
}
return null;
}
/**
* get elasticsearch index doc
*
* @param indexName index name
* @param searchConfigJson search config json
* @param clazz result class
* @param <T> result class obj
* @return doc
*/
public static <T> SearchResponse<T> getDocument(String indexName, String searchConfigJson, Class<T> clazz) {
try {
return elasticsearchClient.search(search -> search.index(indexName).withJson(new StringReader(searchConfigJson)), clazz);
} catch (Exception e) {
log.error("get document error", e);
}
return null;
}
}
运行测试
编写一个测试controller去演示如何去使用工具类
// URL:
http://127.0.0.1:9012/elasticsearch/example/insert
// Param:
[
{
"id": "4977d027-19ac-11ef-84dd-00163e127a93",
"name": "张三",
"age": 7,
"sex": 1,
"birthday": "2011-12-12",
"remark": "一年7班八百标兵奔北坡"
},
{
"id": "5f5d01a2-19ae-11ef-84dd-00163e127a93",
"name": "李四",
"age": 17,
"sex": 1,
"birthday": "2007-10-12",
"remark": "高二三班床前明月光"
},
{
"id": "98727013-19ae-11ef-84dd-00163e127a93",
"name": "王五",
"age": 17,
"sex": 1,
"birthday": "2007-10-12",
"remark": "高二三班飞流直下三千尺"
},
{
"id": "a78915c6-19ae-11ef-84dd-00163e127a93",
"name": "赵六",
"age": 17,
"sex": 1,
"birthday": "2007-10-12",
"remark": "高二三班巴山夜雨涨秋池"
},
{
"id": "0316e1dc-19af-11ef-84dd-00163e127a93",
"name": "小甜甜",
"age": 7,
"sex": 0,
"birthday": "2017-10-12",
"remark": "一年7班黄鹤之飞尚不得过"
}
]
// URL:
http://127.0.0.1:9012/elasticsearch/example/findByRemark
// Param:
remark: '一年级'
代码地址
GitHub - ccx10544/elsaticsearch-util-8: A Simple Elasticsearch Client Util
被墙的话下面是Gitee地址