项目git地址
初始化 springboot 项目
编写application.yml 配置文件
server:
port: 8111
spring:
datasource:
url: jdbc:mysql://localhost:3306/test?useSSL=false&serverTimezone=UTC&characterEncoding=utf8
username: root
password: 123456
driver-class-name: com.mysql.cj.jdbc.Driver
elasticsearch:
rest.uris: http://10.31.1.123:9200
protocol: http
hostname: 10.31.1.123:9200
port: 9200
schema: http
connectTimeOut: 2000
socketTimeOut: 30000
connectionRequestTimeOut: 1000
maxConnectNum: 100
maxConnectPerRoute: 100
username:
password:
pom.xml
<dependency>
<groupId>org.elasticsearch.client</groupId>
<artifactId>elasticsearch-rest-client</artifactId>
<version>7.4.1</version>
</dependency>
<dependency>
<groupId>org.elasticsearch.client</groupId>
<artifactId>elasticsearch-rest-high-level-client</artifactId>
<version>7.4.1</version>
</dependency>
<dependency>
<groupId>org.elasticsearch</groupId>
<artifactId>elasticsearch</artifactId>
<version>7.4.1</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.4</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.54</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.13</version>
</dependency>
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>2.1.0</version>
</dependency>
编写 restHighLevelClient 配置类
package com.es.esdemo.config;
import org.apache.http.HttpHost;
import org.apache.http.auth.AuthScope;
import org.apache.http.auth.UsernamePasswordCredentials;
import org.apache.http.client.CredentialsProvider;
import org.apache.http.impl.client.BasicCredentialsProvider;
import org.elasticsearch.client.RestClient;
import org.elasticsearch.client.RestClientBuilder;
import org.elasticsearch.client.RestHighLevelClient;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.util.StringUtils;
import java.net.URI;
import java.net.URISyntaxException;
@Configuration
public class RestHighLevelClientConfig {
@Value("${spring.elasticsearch.protocol}")
private String protocol;
@Value("${spring.elasticsearch.connectTimeOut}")
private int connectTimeOut;
@Value("${spring.elasticsearch.socketTimeOut}")
private int socketTimeOut;
@Value("${spring.elasticsearch.connectionRequestTimeOut}")
private int connectionRequestTimeOut;
@Value("${spring.elasticsearch.maxConnectNum}")
private int maxConnectNum;
@Value("${spring.elasticsearch.maxConnectPerRoute}")
private int maxConnectPerRoute;
@Value("${spring.elasticsearch.hostname}")
private String hostname;
@Value("${spring.elasticsearch.port}")
private Integer port;
@Value("${spring.elasticsearch.username}")
private String username;
@Value("${spring.elasticsearch.password}")
private String password;
@Value("${spring.elasticsearch.rest.uris}")
private String url;
private static Long keepAlive = 300000L;
@Bean(name = "restHighLevelClient")
public RestHighLevelClient client() {
CredentialsProvider credentialsProvider = new BasicCredentialsProvider();
credentialsProvider.setCredentials(AuthScope.ANY, new UsernamePasswordCredentials(username, password));
RestClientBuilder restClientBuilder = getRestClientBuilder(url)
.setHttpClientConfigCallback(httpClientBuilder -> {
httpClientBuilder.disableAuthCaching();
return httpClientBuilder.setDefaultCredentialsProvider(credentialsProvider);
});
return new RestHighLevelClient(restClientBuilder);
}
public static RestClientBuilder getRestClientBuilder(String esUrl) {
return RestClient.builder(createHttpHost(URI.create(esUrl)));
}
public static HttpHost createHttpHost(URI uri) {
if (StringUtils.isEmpty(uri.getUserInfo())) {
return HttpHost.create(uri.toString());
}
try {
return HttpHost.create(new URI(uri.getScheme(), null, uri.getHost(), uri.getPort(), uri.getPath(),
uri.getQuery(), uri.getFragment()).toString());
} catch (URISyntaxException ex) {
throw new IllegalStateException(ex);
}
}
}
编写restHighLevelClient 操作工具类
package com.es.esdemo.tool;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import lombok.extern.slf4j.Slf4j;
import org.apache.http.HttpHost;
import org.elasticsearch.action.admin.indices.cache.clear.ClearIndicesCacheRequest;
import org.elasticsearch.action.admin.indices.delete.DeleteIndexRequest;
import org.elasticsearch.action.admin.indices.settings.get.GetSettingsRequest;
import org.elasticsearch.action.admin.indices.settings.put.UpdateSettingsRequest;
import org.elasticsearch.action.bulk.BulkRequest;
import org.elasticsearch.action.bulk.BulkResponse;
import org.elasticsearch.action.delete.DeleteRequest;
import org.elasticsearch.action.delete.DeleteResponse;
import org.elasticsearch.action.get.GetRequest;
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.IndicesOptions;
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.RestClient;
import org.elasticsearch.client.RestClientBuilder;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.client.indices.*;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.xcontent.XContentBuilder;
import org.elasticsearch.common.xcontent.XContentType;
import org.elasticsearch.index.reindex.BulkByScrollResponse;
import org.elasticsearch.index.reindex.DeleteByQueryRequest;
import org.elasticsearch.rest.RestStatus;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.SearchHits;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.springframework.util.StringUtils;
import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@Slf4j
public class HighLevelClientUtils {
public static RestHighLevelClient createRestHighLevelClient(String esUrl, Long keepAlive) {
RestClientBuilder clientBuilder = RestClient.builder(createHttpHost(URI.create(esUrl)))
.setHttpClientConfigCallback(requestConfig -> requestConfig.setKeepAliveStrategy(
(response, context) -> keepAlive));
return new RestHighLevelClient(clientBuilder);
}
private static HttpHost createHttpHost(URI uri) {
if (StringUtils.isEmpty(uri.getUserInfo())) {
return HttpHost.create(uri.toString());
}
try {
return HttpHost.create(new URI(uri.getScheme(), null, uri.getHost(), uri.getPort(), uri.getPath(),
uri.getQuery(), uri.getFragment()).toString());
} catch (URISyntaxException ex) {
throw new IllegalStateException(ex);
}
}
public static boolean createIndex(RestHighLevelClient restHighLevelClient, String indexName){
CreateIndexRequest createIndexRequest = new CreateIndexRequest(indexName);
try {
CreateIndexResponse createIndexResponse = restHighLevelClient.indices().create(createIndexRequest, RequestOptions.DEFAULT);
return createIndexResponse.isAcknowledged();
} catch (Exception e) {
log.error("[ElasticSearch]createIndex,indexName={}", JSON.toJSONString(indexName), e);
}
return false;
}
public static boolean createIndex(RestHighLevelClient restHighLevelClient, String indexName, XContentBuilder setting, XContentBuilder mapping) {
try {
CreateIndexRequest createIndexRequest = new CreateIndexRequest(indexName);
createIndexRequest.settings(setting);
createIndexRequest.mapping(mapping);
return restHighLevelClient.indices().create(createIndexRequest, RequestOptions.DEFAULT).isFragment();
} catch (Exception e) {
log.error("[ElasticSearch]createIndex,indexName={}", indexName, e);
}
return false;
}
public static boolean createIndex(RestHighLevelClient restHighLevelClient, String indexName, String setting) {
try {
CreateIndexRequest createIndexRequest = new CreateIndexRequest(indexName);
createIndexRequest.settings(setting, XContentType.JSON);
restHighLevelClient.indices().create(createIndexRequest, RequestOptions.DEFAULT);
return true;
} catch (Exception e) {
log.error("[ElasticSearch]createIndex,indexName={}", indexName, e);
}
return false;
}
public static boolean createIndex(RestHighLevelClient restHighLevelClient, String indexName, String setting, String mapping) {
try {
CreateIndexRequest createIndexRequest = new CreateIndexRequest(indexName);
createIndexRequest.settings(setting, XContentType.JSON);
createIndexRequest.mapping(mapping, XContentType.JSON);
return restHighLevelClient.indices().create(createIndexRequest, RequestOptions.DEFAULT).isFragment();
} catch (Exception e) {
log.error("[ElasticSearch]createIndex,indexName={}", indexName, e);
}
return false;
}
public static boolean createIndex(RestHighLevelClient restHighLevelClient, String indexName, String setting, XContentBuilder mapping) {
try {
CreateIndexRequest createIndexRequest = new CreateIndexRequest(indexName);
createIndexRequest.settings(setting, XContentType.JSON);
createIndexRequest.mapping(mapping);
return restHighLevelClient.indices().create(createIndexRequest, RequestOptions.DEFAULT).isFragment();
} catch (Exception e) {
log.error("[ElasticSearch]createIndex,indexName={}", indexName, e);
}
return false;
}
public static boolean deleteIndex(RestHighLevelClient restHighLevelClient, String indexName) {
try {
DeleteIndexRequest deleteIndexRequest = new DeleteIndexRequest(indexName);
AcknowledgedResponse delete = restHighLevelClient.indices().delete(deleteIndexRequest, RequestOptions.DEFAULT);
return delete.isAcknowledged();
} catch (Exception e) {
log.error("[ElasticSearch]deleteIndex,indexName={}", indexName, e);
}
return false;
}
public static boolean createIndexMapping(RestHighLevelClient restHighLevelClient, String indexName, XContentBuilder mapping) {
PutMappingRequest putMappingRequest = new PutMappingRequest(indexName);
putMappingRequest.source(mapping);
try {
AcknowledgedResponse putMappingResponse = restHighLevelClient.indices().putMapping(putMappingRequest, RequestOptions.DEFAULT);
System.out.println(putMappingResponse);
return putMappingResponse.isAcknowledged();
} catch (IOException e) {
log.error("[ElasticSearch]createIndexMapping,indexName={}", JSON.toJSONString(indexName), e);
}
return false;
}
public static String getIndexSettings(RestHighLevelClient restHighLevelClient, String indexName) {
try {
GetSettingsRequest request = new GetSettingsRequest().indices(indexName);
Settings indexSettings = restHighLevelClient.indices().getSettings(request, RequestOptions.DEFAULT).getIndexToSettings().get(indexName);
return JSONObject.toJSONString(indexSettings);
}catch (Exception e){
log.error("[ElasticSearch]createIndexMapping,indexName={}", JSON.toJSONString(indexName), e);
}
return null;
}
public static boolean updateIndexSettings(RestHighLevelClient restHighLevelClient, String indexName, String setting) {
try {
UpdateSettingsRequest request = new UpdateSettingsRequest(indexName);
request.settings(setting, XContentType.JSON);
return restHighLevelClient.indices().putSettings(request, RequestOptions.DEFAULT).isAcknowledged();
}catch (Exception e){
log.error("[ElasticSearch]deleteDoc", e);
}
return false;
}
public static boolean indexExists(RestHighLevelClient restHighLevelClient, String indexName) {
try {
GetIndexRequest getIndexRequest = new GetIndexRequest(indexName);
return restHighLevelClient.indices().exists(getIndexRequest, RequestOptions.DEFAULT);
} catch (Exception e) {
log.error("[ElasticSearch]indexExists,indexName={}", indexName, e);
}
return false;
}
public static boolean updateDoc(RestHighLevelClient restHighLevelClient, String indexName, Object targetVo, String id){
try {
if(targetVo != null && !StringUtils.isEmpty(id)){
GetRequest getRequest = new GetRequest(indexName, id);
boolean exists = restHighLevelClient.exists(getRequest, RequestOptions.DEFAULT);
if(exists){
UpdateRequest updateRequest = new UpdateRequest(indexName, id).doc(JSON.toJSONString(targetVo), XContentType.JSON);
UpdateResponse update = restHighLevelClient.update(updateRequest, RequestOptions.DEFAULT);
log.info("[ElasticSearch]updateDocs indexName:{},response:{}", indexName, update);
}else{
IndexRequest indexRequest = new IndexRequest(indexName).id(id).source(JSON.toJSONString(targetVo), XContentType.JSON);
IndexResponse index = restHighLevelClient.index(indexRequest, RequestOptions.DEFAULT);
log.info("[ElasticSearch]updateDocs indexName:{},response:{}", indexName, index);
}
return true;
}
}catch (Exception e){
log.error("[ElasticSearch]updateDoc,indexName={}", indexName, e);
}
return false;
}
public static boolean updateDocs(RestHighLevelClient restHighLevelClient, String indexName, String voListStr, String idKeyStr){
try {
BulkRequest bulkRequest = new BulkRequest();
if(StringUtils.isEmpty(voListStr)){
return false;
}
List<Object> voList = JSONArray.parseArray(voListStr, Object.class);
voList.forEach( vo -> {
Map<String, Object> map = JSONObject.parseObject(JSONObject.toJSONString(vo), Map.class);
if(map.containsKey(idKeyStr)){
IndexRequest indexRequest = new IndexRequest(indexName).source(map, XContentType.JSON).id(map.get(idKeyStr) + "");
bulkRequest.add(indexRequest);
}
});
BulkResponse response = restHighLevelClient.bulk(bulkRequest, RequestOptions.DEFAULT);
log.info("[ElasticSearch]updateDocs indexName:{},response:{}", indexName, response);
return !response.hasFailures();
}catch (Exception e){
log.error("[ElasticSearch]updateDocs,indexName={}", indexName, e);
}
return false;
}
public static boolean deleteDoc(RestHighLevelClient restHighLevelClient, String indexName, String id){
try {
DeleteRequest deleteRequest = new DeleteRequest(indexName);
deleteRequest.id(id);
DeleteResponse response = restHighLevelClient.delete(deleteRequest, RequestOptions.DEFAULT);
log.info("[ElasticSearch]deleteDoc indexName:{},response:{}", indexName, response);
return true;
} catch (Exception e) {
log.error("[ElasticSearch]deleteDoc,indexName={}", indexName, e);
}
return false;
}
public static boolean deleteDocByQuery(RestHighLevelClient restHighLevelClient, String indexName, DeleteByQueryRequest request){
try {
BulkByScrollResponse response = restHighLevelClient.deleteByQuery(request, RequestOptions.DEFAULT);
log.info("[ElasticSearch]deleteDocByQuery indexName:{},response:{}", indexName, response);
return true;
} catch (Exception e) {
log.error("[ElasticSearch]deleteDocByQuery,indexName={}", indexName, e);
}
return false;
}
public static void clearCache(RestHighLevelClient restHighLevelClient) {
try {
ClearIndicesCacheRequest requestAll = new ClearIndicesCacheRequest();
requestAll.indicesOptions(IndicesOptions.lenientExpandOpen());
restHighLevelClient.indices().clearCache(requestAll, RequestOptions.DEFAULT);
} catch (Exception e){
log.error("[ElasticSearch]deleteDoc", e);
}
}
public static Map<String, Object> getIgnoreNullMap(Object vo){
if(StringUtils.isEmpty(vo)){
return null;
}
Map<String, Object> targetMap = new HashMap(16);
try {
Map<String, Object> map = JSONObject.parseObject(JSONObject.toJSONString(vo), Map.class);
if(map == null){
return null;
}
map.forEach((key, value) -> {
if(!StringUtils.isEmpty(value)){
targetMap.put(key, value);
}
});
}catch (Exception e){
log.error("vo 转 Map失败,e" + e);
return null;
}
return targetMap;
}
public static SearchResponse search(RestHighLevelClient restHighLevelClient, String indexName, SearchSourceBuilder searchSourceBuilder){
try{
List<String> voList = new ArrayList<>();
SearchRequest searchRequest = new SearchRequest();
searchRequest.indices(indexName);
searchRequest.source(searchSourceBuilder);
SearchResponse searchResponse = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);
if (RestStatus.OK.equals(searchResponse.status()) && searchResponse.getHits().getTotalHits().value > 0) {
SearchHits hits = searchResponse.getHits();
for (SearchHit hit : hits) {
voList.add(hit.getSourceAsString());
}
}
return searchResponse;
}catch (Exception e){
log.error("[ElasticSearch]search", e);
}
return null;
}
}
如何使用
package com.es.esdemo.entity;
import lombok.Data;
import org.elasticsearch.common.xcontent.XContentBuilder;
import org.elasticsearch.common.xcontent.XContentFactory;
import org.springframework.util.ResourceUtils;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStreamReader;
@Data
public class CmsDoc {
public static final String IK= "ik_max_word";
public static final String COMMA= "comma";
public static final String ID = "id";
public static final String TITLE = "title";
public static final String TAGS = "tags";
public static final String CONTENT = "content";
public static final String UPDATE_TIME = "updateTime";
public static final String CREATE_TIME = "createTime";
private Integer id;
private String title;
private String tags;
private String content;
private Long updateTime;
private Long createTime;
public static String buildSetting(){
StringBuffer str = new StringBuffer();
File jsonFile = null;
try {
jsonFile = ResourceUtils.getFile("classpath:cms-setting.json");
FileInputStream fis = new FileInputStream(jsonFile);
BufferedReader br = new BufferedReader(new InputStreamReader(fis));
String line;
while ((line = br.readLine()) != null) {
str.append(line);
}
fis.close();
} catch (Exception e) {
e.printStackTrace();
}
System.out.println(str);
return str.toString();
}
public static XContentBuilder buildIndexMapping() {
XContentBuilder contentBuilder = null;
try {
contentBuilder = XContentFactory.jsonBuilder();
contentBuilder.startObject();
contentBuilder.startObject("properties");
contentBuilder.startObject(CmsDoc.ID).field("type", "long").field("store", "true").endObject();
contentBuilder.startObject(CmsDoc.TITLE)
.field("analyzer", IK)
.field("type", "text")
.field("store", "true")
.endObject();
contentBuilder.startObject(CmsDoc.TAGS).field("analyzer", COMMA)
.field("type", "text")
.field("store", "true")
.endObject();
contentBuilder.startObject(CmsDoc.CONTENT).field("analyzer", IK)
.field("type", "text")
.field("store", "true")
.endObject();
contentBuilder.startObject(CmsDoc.CREATE_TIME).field("type", "long").field("store", "true").endObject();
contentBuilder.startObject(CmsDoc.UPDATE_TIME).field("type", "long").field("store", "true").endObject();
contentBuilder.endObject();
contentBuilder.endObject();
}catch (Exception e){
}
return contentBuilder;
}
}
package com.es.esdemo.service;
import com.alibaba.fastjson.JSONArray;
import com.es.esdemo.dao.CmsDao;
import com.es.esdemo.entity.Cms;
import com.es.esdemo.entity.CmsDoc;
import com.es.esdemo.tool.HighLevelClientUtils;
import lombok.extern.slf4j.Slf4j;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.common.xcontent.XContentBuilder;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.elasticsearch.search.sort.SortOrder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;
import javax.annotation.Resource;
import java.util.List;
@Service
@Slf4j
public class CmsService {
private String indexName = "cms_index";
@Resource
private CmsDao cmsDao;
@Autowired
private RestHighLevelClient restHighLevelClient;
public List<Cms> getList(){
return cmsDao.getList();
}
public Boolean createIndex() {
if(HighLevelClientUtils.indexExists(restHighLevelClient, indexName)){
log.info("createIndex:{} 已存在", indexName);
}
boolean index = HighLevelClientUtils.createIndex(restHighLevelClient, indexName, CmsDoc.buildSetting());
if(!index) {
log.info("createIndex:{} 失败", indexName);
return false;
}
XContentBuilder mapping = CmsDoc.buildIndexMapping();
if (mapping != null) {
return HighLevelClientUtils.createIndexMapping(restHighLevelClient, indexName, mapping);
}
return false;
}
public Boolean deleteIndex() {
if(!HighLevelClientUtils.indexExists(restHighLevelClient, indexName)){
log.info("createIndex:{} 不存在", indexName);
return true;
}
return HighLevelClientUtils.deleteIndex(restHighLevelClient, indexName);
}
public Integer rebuildIndex() {
List<Cms> list = cmsDao.getList();
if (list != null && list.size() > 0) {
HighLevelClientUtils.updateDocs(restHighLevelClient, indexName, JSONArray.toJSONString(list), CmsDoc.ID);
return list.size();
}
return 0;
}
public Object searchList(Integer pageNo, Integer pageSize, Integer id, String keyword) {
int startNum = (pageNo - 1) * pageSize;
SearchSourceBuilder searchBuilder = new SearchSourceBuilder();
BoolQueryBuilder boolQuery = QueryBuilders.boolQuery();
if(id != null){
boolQuery.should(QueryBuilders.termQuery(CmsDoc.ID, keyword));
}
if(!StringUtils.isEmpty(keyword)){
boolQuery.should(QueryBuilders.matchQuery(CmsDoc.TITLE, keyword).analyzer(CmsDoc.IK));
boolQuery.should(QueryBuilders.matchQuery(CmsDoc.TAGS, keyword).analyzer(CmsDoc.COMMA));
boolQuery.should(QueryBuilders.matchQuery(CmsDoc.CONTENT, keyword).analyzer(CmsDoc.IK));
}
searchBuilder.query(boolQuery);
searchBuilder.from(startNum);
searchBuilder.size(pageSize);
searchBuilder.sort(CmsDoc.ID, SortOrder.DESC);
return HighLevelClientUtils.search(restHighLevelClient, indexName, searchBuilder);
}
}