yml文件配置:
##ElasticSearch服务配置 for highLevelRestClient
esclient:
master-host: xxx.xxx.xxx.xxx(安装es服务器的IP地址)
master-port: 9200(安装的端口)
master-user-name: xxx(服务器用户名)
master-user-pwd: xxx(服务器密码)
添加依赖:
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-elasticsearch</artifactId> </dependency>
import lombok.extern.slf4j.Slf4j;
import org.elasticsearch.action.admin.indices.alias.Alias;
import org.elasticsearch.action.support.master.AcknowledgedResponse;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.client.indices.IndexTemplatesExistRequest;
import org.elasticsearch.client.indices.PutIndexTemplateRequest;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.xcontent.XContentBuilder;
import org.elasticsearch.common.xcontent.XContentFactory;
public class esTemplate {
@Autowired
private RestHighLevelClient restHighLevelClient;
//判断是否存在对应的索引,indexName--索引的名称
private boolean checkTemplateExists(String indexName)throws IOException {
IndexTemplatesExistRequest request = new IndexTemplatesExistRequest(indexName);
boolean response = restHighLevelClient.indices().existsTemplate(request, RequestOptions.DEFAULT);
return response;
}
//模版创建
public Result<?> initIndexTemplate() throws IOException {
PutIndexTemplateRequest request = new PutIndexTemplateRequest("xxx添加索引的名称");
//别名,所有根据该模版创建的index //都会添加这个别名。查询时可查询别名,就可以同时查询多个名称不同的index,根据此方法可实现index每天或每月生成等逻辑。
request.alias(new Alias("index对应的别名名称"));
//匹配哪些index。在创建index时会生效。
request.patterns(CollUtil.newArrayList("index名称" + "*"));
request.order(3);
request.settings(Settings.builder()
//数据插入后多久能查到,实时性要求高可以调低
.put("index.refresh_interval", "10s")
//传输日志,对数据安全性要求高的 设置 request,默认值:request
.put("index.translog.durability", "async")
.put("index.translog.sync_interval", "120s")
//分片数量
.put("index.number_of_shards", "2")
//副本数量
.put("index.number_of_replicas", "0")
//单次最大查询数据的数量。默认10000。不要设置太高,如果有导出需求可以根据查询条件分批次查询。
.put("index.max_result_window", "1000"));
//使用官方提供的工具构建json。可以直接拼接一个json字符串,也可以使用map嵌套。
XContentBuilder jsonMapping = XContentFactory.jsonBuilder();
//所有数据类型 看官方文档:https://www.elastic.co/guide/en/elasticsearch/reference/7.4/mapping-types.html#_core_datatypes
//keyword类型不会分词存储
jsonMapping.startObject().startObject("properties")
.startObject("id").field("type", "keyword").endObject()
//integer-对应int类型
.startObject("字段名称A").field("type", "integer").endObject()
//keyword--对应string类型
.startObject("字段名称B").field("type", "keyword").endObject()
.startObject("字段名称C").field("type", "date").field("format", DatePattern.NORM_DATE_PATTERN).endObject()
//text--对应的string类型
//field("analyzer", "ik_max_word")--固定格式,指定分词器,当前字段内容入库ES之后,需要进行分词的内容
//ik_max_word--分词的类型,进行最细粒度的拆分;ik_smart--进行粗粒度的拆分
.startObject("字段名称D").field("type", "text").field("analyzer", "ik_max_word").endObject()
.startObject("字段名称E").field("type","keyword").endObject()
.endObject().endObject();
request.mapping(jsonMapping);
//设置为true只强制创建,而不是更新索引模板。如果它已经存在,它将失败
request.create(false);
AcknowledgedResponse response = restHighLevelClient.indices().putTemplate(request, RequestOptions.DEFAULT);
if (response.isAcknowledged()) {
return Result.OK("创建模版成功!");
} else {
return Result.error("创建模版失败!");
}
}
//入库ES,entity--入库的实体,注意实体的属性要和上面index创建模版时候的字段属性一致
public void saveEs(Entity entity) {
//插入数据,index不存在则自动根据匹配到的template创建。index没必要每天创建一个,如果是为了灵活管理,最低建议每月一个 yyyyMM。
IndexRequest indexRequest = new IndexRequest("索引名称");
//考虑大文件,允许1小时超时时间,前提是异步执行入库ES
indexRequest.timeout(TimeValue.timeValueHours(1));
indexRequest.source(new JSONObject(entity,
new JSONConfig().setDateFormat(DatePattern.NORM_DATE_PATTERN)).toString()
, XContentType.JSON);
IndexResponse response = restHighLevelClient.index(indexRequest, RequestOptions.DEFAULT);
if (!response.status().equals(RestStatus.CREATED)) {
return Result.error("入库ES发生错误,返回码[" + response.status().toString() + "]");
} else {
return Result.OK(response.getId());
}
}
//查询index中某条id的数据,并进行更新,entity-更新的实体,indexId--对应index中某条id
public SearchResponse search(Entity entity,String indexId) {
//通过索引id查询
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
QueryBuilder queryBuilder = QueryBuilders.idsQuery().addIds(indexId);
searchSourceBuilder.query(queryBuilder);
//超时 10S
searchSourceBuilder.timeout(new TimeValue(10, TimeUnit.SECONDS));
SearchRequest searchRequest = new SearchRequest();
searchRequest.source(searchSourceBuilder);
searchRequest.indices("index名称");
SearchResponse searchResponse = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);
if(searchResponse.status() != RestStatus.OK){
return Result.error("从ES查询文档索引失败");
}
else{
long c = searchResponse.getHits().getTotalHits().value;
if(c == 0){
indexExistFlag = false;
}
else{
//更新ES记录
UpdateRequest updateRequest = new UpdateRequest("index名称",indexId);
updateRequest.timeout(TimeValue.timeValueHours(1));
updateRequest.doc(new JSONObject(entity,
new JSONConfig().setDateFormat(DatePattern.NORM_DATE_PATTERN)).toString()
,XContentType.JSON);
updateRequest.setRefreshPolicy(WriteRequest.RefreshPolicy.IMMEDIATE);
UpdateResponse updateResponse = restHighLevelClient.update(updateRequest,RequestOptions.DEFAULT);
if (!updateResponse.status().equals(RestStatus.OK)) {
return Result.error("更新ES发生错误,返回码[" + updateResponse.status().toString() + "]");
} else {
return Result.OK();
}
}
}
}
//删除数据
public void deleteIndex(String indexId){
DeleteRequest deleteRequest = new DeleteRequest("index的名称",indexId);
deleteRequest.timeout(TimeValue.timeValueHours(1));
deleteRequest.setRefreshPolicy(WriteRequest.RefreshPolicy.IMMEDIATE);
DeleteResponse deleteResponse = restHighLevelClient.delete(deleteRequest,RequestOptions.DEFAULT);
if (!deleteResponse.status().equals(RestStatus.OK)) {
log.info("从ES删除文档失败:{}",indexId);
return Result.error("从ES删除文档发生错误,返回码[" + deleteResponse.status().toString() + "]");
} else {
log.info("从ES删除文档成功:{}",indexId);
return Result.OK("从ES删除文档成功");
}
}