springboot引入Elasticsearch
Posted 梦想载旺
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了springboot引入Elasticsearch相关的知识,希望对你有一定的参考价值。
之前在工程中日志信息存储在mysql中,由于日志越来越大,导致查询效率越来越慢,想着运用Elasticsearch提高效率,自己结合情况,花了半天时间写了一套springboot引用Elasticsearch。
一 :创建SpringBoot项目并引入Elasticsearch依赖
引入相关jar包,具体如下(注意与springboot版本相对应):
<dependency>
<groupId>org.elasticsearch</groupId>
<artifactId>elasticsearch</artifactId>
<version>7.17.9</version>
</dependency>
<dependency>
<groupId>org.elasticsearch.client</groupId>
<artifactId>transport</artifactId>
<version>7.17.9</version>
</dependency>
<dependency>
<groupId>org.elasticsearch.client</groupId>
<artifactId>elasticsearch-rest-high-level-client</artifactId>
<version>7.17.9</version>
</dependency>
二 :SpringBoot项目配置相应配置信息
配置相应的Elasticsearch,具体如下:
spring:
elasticsearch:
host: 127.0.0.1
port: 9200
connTimeout: 3000
socketTimeout: 5000
connectionRequestTimeout: 500
三 :SpringBoot项目配置相应配置客户端
配置读取配置的类:
import lombok.Data;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
@Data
@Component
public class EsConfig
@Value("$spring.elasticsearch.host")
private String host;
@Value("$spring.elasticsearch.port")
private int port;
@Value("$spring.elasticsearch.connTimeout")
private int connTimeout;
@Value("$spring.elasticsearch.socketTimeout")
private int socketTimeout;
@Value("$spring.elasticsearch.connectionRequestTimeout")
private int connectionRequestTimeout;
创建连接Elasticsearch连接的客户端:
import com.huanggr.common.core.domain.EsConfig;
import lombok.extern.slf4j.Slf4j;
import org.apache.http.HttpHost;
import org.elasticsearch.client.RestClient;
import org.elasticsearch.client.RestClientBuilder;
import org.elasticsearch.client.RestHighLevelClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.stereotype.Component;
@Slf4j
@Configuration
@Component
public class ElasticsearchConfiguration
@Autowired
EsConfig esConfig;
@Bean(destroyMethod = "close", name = "client")
public RestHighLevelClient initRestClient()
RestClientBuilder builder = RestClient.builder(new HttpHost(esConfig.getHost(), esConfig.getPort()))
.setRequestConfigCallback(requestConfigBuilder -> requestConfigBuilder
.setConnectTimeout(esConfig.getConnTimeout())
.setSocketTimeout(esConfig.getSocketTimeout())
.setConnectionRequestTimeout(esConfig.getConnectionRequestTimeout()));
return new RestHighLevelClient(builder);
// 注册 rest高级客户端
@Bean
public RestHighLevelClient restHighLevelClient()
RestHighLevelClient client = new RestHighLevelClient(
RestClient.builder(
new HttpHost(esConfig.getHost(), esConfig.getPort(), "http")
)
);
return client;
四 :配置相应的Elasticsearch的操作类
配置相应的枚举:
/**
* Es查询类型
*
* @author huanggr
*/
public enum EsQueryType
term("term", "精确值查找"),
range("range", "范围检索"),
prefix("prefix", "模糊查询");
public String code;
public String value;
EsQueryType(String code, String value)
this.code = code;
this.value = value;
public String getCode()
return code;
public String getValue()
return value;
public enum RangeType
lte("lte","小于或等于"),
lt("lt","小于"),
gt("gt","大于"),
gte("gte","大于或等于");
private final String code;
private final String value;
RangeType(String code, String value)
this.code = code;
this.value = value;
public String getCode()
return code;
public String getValue()
return value;
配置相应的实体类:
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
@Data
public class EsQueryVo
@ApiModelProperty(value = "参数主键")
private String name;
@ApiModelProperty(value = "参数主键值")
private String value;
@ApiModelProperty(value = "查询类型")
private String queryType;
@ApiModelProperty(value = "大于或者大于等于或者小于或者等于")
private String gteandlte;
public EsQueryVo()
public EsQueryVo(String name, String value,String queryType,String gteandlte)
this.name = name;
this.value = value;
this.queryType = queryType;
this.gteandlte = gteandlte;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.util.List;
import java.util.Map;
@Data
public class PageList
@ApiModelProperty(value = "集合")
private List<Map<String,Object>> hitList;
@ApiModelProperty(value = "总数")
private long total;
配置EsManageService相应操作管理类:
import com.alibaba.fastjson2.JSON;
import com.huanggr.common.core.domain.EsQueryVo;
import com.huanggr.common.core.domain.PageList;
import com.huanggr.common.core.enums.EsQueryType;
import com.huanggr.common.core.enums.RangeType;
import lombok.extern.slf4j.Slf4j;
import org.elasticsearch.action.admin.indices.create.CreateIndexRequest;
import org.elasticsearch.action.admin.indices.create.CreateIndexResponse;
import org.elasticsearch.action.admin.indices.delete.DeleteIndexRequest;
import org.elasticsearch.action.delete.DeleteRequest;
import org.elasticsearch.action.delete.DeleteResponse;
import org.elasticsearch.action.index.IndexRequest;
import org.elasticsearch.action.index.IndexResponse;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.action.support.master.AcknowledgedResponse;
import org.elasticsearch.action.update.UpdateRequest;
import org.elasticsearch.action.update.UpdateResponse;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.client.indices.GetIndexRequest;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.rest.RestStatus;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.elasticsearch.xcontent.XContentType;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@Service
@Slf4j
public class EsManageService
@Autowired
@Qualifier("restHighLevelClient")
public RestHighLevelClient client;
/**
* 创建索引
* @param index 索引名称
* @param map key的Map
* @return boolean
* @throws IOException
*/
public boolean createIndex(String index,Map<String,Object> map) throws IOException
//校验索引是否存在
GetIndexRequest getRequest = new GetIndexRequest(index);
if(client.indices().exists(getRequest,RequestOptions.DEFAULT))
log.info("已存在索引",index);
return true;
CreateIndexRequest createIndexRequest = new CreateIndexRequest(index);
createIndexRequest.settings(Settings.builder()
.put("index.number_of_shards", 1)
.put("index.number_of_replicas", 0)
);
createIndexRequest.mapping("_doc",map);
CreateIndexResponse createIndexResponse = client.indices().create(createIndexRequest, RequestOptions.DEFAULT);
return createIndexResponse.isAcknowledged();
/**
* 创建索引
* @param index 索引名称
* @param JsonString String
* @return boolean
* @throws IOException
*/
public boolean createIndex(String index,String JsonString)throws IOException
//校验索引是否存在
GetIndexRequest getRequest = new GetIndexRequest(index);
if(client.indices().exists(getRequest,RequestOptions.DEFAULT))
log.info("已存在索引",index);
return true;
CreateIndexRequest createIndexRequest = new CreateIndexRequest(index);
createIndexRequest.settings(Settings.builder()
.put("index.number_of_shards", 1)
.put("index.number_of_replicas", 0)
);
createIndexRequest.mapping("_doc",JsonString, XContentType.JSON);
CreateIndexResponse createIndexResponse = client.indices().create(createIndexRequest, RequestOptions.DEFAULT);
return createIndexResponse.isAcknowledged();
//删除索引(删表)
public Boolean deleteIndex(String index) throws IOException
DeleteIndexRequest deleteIndexRequest = new DeleteIndexRequest(index);
AcknowledgedResponse deleteIndexResponse = client.indices().delete(deleteIndexRequest, RequestOptions.DEFAULT);
return deleteIndexResponse.isAcknowledged();
//创建文档(插入数据)
public Boolean createDocumentByHashMap(HashMap<String,Object> map, String index, String id) throws Exception
IndexRequest indexRequest = new IndexRequest(index)
.id(id).source(map);
IndexResponse indexResponse = client.index(indexRequest, RequestOptions.DEFAULT);
return ((IndexResponse) indexResponse).status().equals(RestStatus.OK);
//更新文档
public Boolean updateDocumentByMap(HashMap<String,Object> map, String index, String id) throws Exception
UpdateRequest updateRequest = new UpdateRequest(index, id);
updateRequest.doc(map);
UpdateResponse updateResponse = client.update(updateRequest, RequestOptions.DEFAULT);
return updateResponse.status().equals(RestStatus.OK);
//删除文档
public String deleteDocument(String id,String index) throws Exception
DeleteRequest deleteRequest = new DeleteRequest(index, id);
DeleteResponse response = client.delete(deleteRequest, RequestOptions.DEFAULT);
return response.getResult().name();
//查询Es文档
public PageList searchListByPage(String index, List<EsQueryVo> esQueryVos, int pageNum, int pageSize) throws IOException
PageList pageList = new PageList();
List<Map<String,Object>> hitList = new ArrayList();
SearchRequest searchRequest = new SearchRequest(index);
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
BoolQueryBuilder queryBuilder = new BoolQueryBuilder();
if(esQueryVos != null && esQueryVos.size()>0)
for (EsQueryVo esQueryVo:
esQueryVos)
clboolQueryBuilder(queryBuilder,esQueryVo);
else
queryBuilder.must(QueryBuilders.matchAllQuery());
log.info("queryBuilder查询条件:", queryBuilder.toString());
searchSourceBuilder.query(queryBuilder);
searchSourceBuilder.from((pageNum-1)*pageSize);
searchSourceBuilder.size(pageSize);
searchRequest.source(searchSourceBuilder);
SearchResponse searchResponse = client.search(searchRequest,RequestOptions.DEFAULT);
long total = searchResponse.getHits().getTotalHits().value;
for (SearchHit hit : searchResponse.getHits().getHits())
hitList.add(hit.getSourceAsMap());
log.info("查询结果:", hit.getSourceAsString());
pageList.setHitList(hitList);
pageList.setTotal(total);
return pageList;
public List<Map<String,Object>> searchList(String index, List<EsQueryVo> esQueryVos) throws IOException
List<Map<String,Object>> hitList = new ArrayList();
SearchRequest searchRequest = new SearchRequest(index);
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
BoolQueryBuilder queryBuilder = new BoolQueryBuilder();
if(esQueryVos != null && esQueryVos.size()>0)
for (EsQueryVo esQueryVo:
esQueryVos)
clboolQueryBuilder(queryBuilder,esQueryVo);
else
queryBuilder.must(QueryBuilders.matchAllQuery());
log.info("queryBuilder查询条件:", queryBuilder.toString());
searchSourceBuilder.query(queryBuilder);
searchRequest.source(searchSourceBuilder);
SearchResponse searchResponse = client.search(searchRequest,RequestOptions.DEFAULT);
long total = searchResponse.getHits().getTotalHits().value;
for (SearchHit hit : searchResponse.getHits().getHits())
hitList.add(hit.getSourceAsMap());
log.info("查询结果:", hit.getSourceAsString());
return hitList;
/**
* 处理流程
* @param boolQueryBuilder
* @param esQueryVo
*/
public void clboolQueryBuilder(BoolQueryBuilder boolQueryBuilder,EsQueryVo esQueryVo)
if(EsQueryType.term.getCode().equals(esQueryVo.getQueryType()))
boolQueryBuilder.must(QueryBuilders.termsQuery(esQueryVo.getName(),esQueryVo.getValue()));
else if(EsQueryType.prefix.getCode().equals(esQueryVo.getQueryType()))
boolQueryBuilder.must(QueryBuilders.prefixQuery(esQueryVo.getName(),esQueryVo.getValue()));
else if(EsQueryType.range.getCode().equals(esQueryVo.getQueryType()))
if(RangeType.gt.getCode().equals(esQueryVo.getGteandlte()))
boolQueryBuilder.must(QueryBuilders.rangeQuery(esQueryVo.getName()).gt(esQueryVo.getValue()));
else if(RangeType.gte.getCode().equals(esQueryVo.getGteandlte()))
boolQueryBuilder.must(QueryBuilders.rangeQuery(esQueryVo.getName()).gte(esQueryVo.getValue()));
else if(RangeType.lt.getCode().equals(esQueryVo.getGteandlte()))
boolQueryBuilder.must(QueryBuilders.rangeQuery(esQueryVo.getName()).lt(esQueryVo.getValue()));
else
boolQueryBuilder.must(QueryBuilders.rangeQuery(esQueryVo.getName()).lte(esQueryVo.getValue()));
else
log.error("不存在queryType",esQueryVo.getQueryType());
throw new RuntimeException("不存在"+esQueryVo.getQueryType()+"queryType");
四 :相应的运用:
import com.huanggr.common.core.constant.Constants;
import com.huanggr.common.core.domain.EsQueryVo;
import com.huanggr.common.core.domain.PageList;
import com.huanggr.common.core.enums.EsQueryType;
import com.huanggr.common.log.service.EsManageService;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
@Component
public class ApplicationInitEsCreate implements ApplicationRunner
@Resource
private EsManageService esManageService;
@Override
public void run(ApplicationArguments args) throws Exception
String JsonObject =getOperLogJson();
esManageService.createIndex(Constants.INDEX_SYS_LOGS,JsonObject);
List<EsQueryVo> esQueryVos = new ArrayList<>();
EsQueryVo esQueryVo = new EsQueryVo("operName","ad", EsQueryType.prefix.getCode(),null);
esQueryVos.add(esQueryVo);
PageList res = esManageService.searchListByPage(Constants.INDEX_SYS_LOGS,esQueryVos,1,10);
public String getOperLogJson()
return "\\n" +
" \\"properties\\":\\n" +
" \\"operId\\":\\n" +
" \\"type\\":\\"long\\"\\n" +
" ,\\n" +
" \\"businessType\\":\\n" +
" \\"type\\":\\"integer\\"\\n" +
" ,\\n" +
" \\"businessTypes\\":\\n" +
" \\"type\\":\\"keyword\\"\\n" +
" ,\\n" +
" \\"method\\":\\n" +
" \\"type\\":\\"keyword\\"\\n" +
" ,\\n" +
" \\"requestMethod\\":\\n" +
" \\"type\\":\\"keyword\\"\\n" +
" ,\\n" +
" \\"operatorType\\":\\n" +
" \\"type\\":\\"integer\\"\\n" +
" ,\\n" +
" \\"operName\\":\\n" +
" \\"type\\":\\"keyword\\"\\n" +
" ,\\n" +
" \\"deptName\\":\\n" +
" \\"type\\":\\"keyword\\"\\n" +
" ,\\n" +
" \\"operUrl\\":\\n" +
" \\"type\\":\\"keyword\\"\\n" +
" ,\\n" +
" \\"operIp\\":\\n" +
" \\"type\\":\\"keyword\\"\\n" +
" ,\\n" +
" \\"operParam\\":\\n" +
" \\"type\\":\\"keyword\\"\\n" +
" ,\\n" +
" \\"jsonResult\\":\\n" +
" \\"type\\":\\"keyword\\"\\n" +
" ,\\n" +
" \\"status\\":\\n" +
" \\"type\\":\\"integer\\"\\n" +
" ,\\n" +
" \\"errorMsg\\":\\n" +
" \\"type\\":\\"keyword\\"\\n" +
" ,\\n" +
" \\"startDate\\": \\n" +
" \\"format\\": \\"yyyy-MM-dd HH:mm:ss||yyyy-MM-dd||epoch_millis\\",\\n" +
" \\"type\\": \\"date\\"\\n" +
" ,\\n" +
" \\"costTime\\":\\n" +
" \\"type\\":\\"long\\"\\n" +
" ,\\n" +
" \\"title\\":\\n" +
" \\"type\\":\\"keyword\\"\\n" +
" \\n" +
" \\n" +
"";
import com.alibaba.fastjson2.JSON;
import com.huanggr.common.core.constant.Constants;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import com.huanggr.common.core.constant.SecurityConstants;
import com.huanggr.system.api.RemoteLogService;
import com.huanggr.system.api.domain.SysOperLog;
import javax.annotation.Resource;
import java.util.Date;
import java.util.HashMap;
import java.util.UUID;
/**
* 异步调用日志服务
*
* @author huanggr
*/
@Service
public class AsyncLogService
@Autowired
private RemoteLogService remoteLogService;
@Resource
private EsManageService esManageService;
/**
* 保存系统日志记录
*/
@Async
public void saveSysLog(SysOperLog sysOperLog)
remoteLogService.saveLog(sysOperLog, SecurityConstants.INNER);
@Async
public void saveSysLogEs(SysOperLog sysOperLog) throws Exception
sysOperLog.setOperTime(new Date());
HashMap<String,Object> map = JSON.parseObject(JSON.toJSONString(sysOperLog), HashMap.class);
esManageService.createDocumentByHashMap(map, Constants.INDEX_SYS_LOGS, UUID.randomUUID().toString());
以上是关于springboot引入Elasticsearch的主要内容,如果未能解决你的问题,请参考以下文章
架构师成长记_第八周_21_Springboot 整合 elasticsearch
架构师成长记_第八周_21_Springboot 整合 elasticsearch
ELK SpringData框架 Springboot集成elasticSearch
Elasticsearch7.8.0版本入门——JavaAPI操作(环境准备)