1. 集群的搭建
見:ElasticSearch(七)
2. springboot配置集群
2.1 創建springboot項目,使用idea創建,不過多介紹(創建項目時候建議不要勾選elasticsearch,springboot目前自帶的elasticsearch版本為5.6.10,如果你版本高於這個版本,還是自己手動導入。)
2.2 導入依賴
<properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> <java.version>1.8</java.version> <elasticSearch.version>6.3.2</elasticSearch.version> </properties>
<dependency> <groupId>org.elasticsearch</groupId> <artifactId>elasticsearch</artifactId> <version>${elasticSearch.version}</version> </dependency> <dependency> <groupId>org.elasticsearch.client</groupId> <artifactId>transport</artifactId> <version>${elasticSearch.version}</version> <exclusions> <exclusion> <groupId>org.elasticsearch</groupId> <artifactId>elasticsearch</artifactId> </exclusion> </exclusions> </dependency> <dependency> <groupId>org.elasticsearch.client</groupId> <artifactId>elasticsearch-rest-high-level-client</artifactId> <version>${elasticSearch.version}</version> </dependency> <dependency> <groupId>org.elasticsearch.plugin</groupId> <artifactId>transport-netty4-client</artifactId> <version>${elasticSearch.version}</version> </dependency>
對於依賴需要說明的幾點:
2.2.1. org.elasticsearch.client--transport 依賴添加之后,會依賴一系列的插件,客戶端等,雖然在springboot2.0中依舊依賴 org.elasticsearch-elasticsearch-6.3.2,但是在依賴列表中,其添加的依賴依然是elasticSearch5.6.10的依賴,所以必須排除這個依賴,手動添加org.elasticsearch-elasticsearch6.3.2的依賴,目前只有這種解決方法,否則導致版本不一致沖突。如下:
當我排除 org.elasticsearch.client.transport的elasticsearch的依賴之后,重新添加elasticsearch 6.3.2的依賴之后,就顯示的是同樣的elasticsearch6.3.2。顯示如下:
2.2.2. 這時候如果你再springboot中配置了TransportClient的方法Bean,則啟動項目,會報錯:
這是因為:transport-netty4-client的版本是5.6.0,而我們使用的所有的elasticsearch版本都是6.3.2,導致jar包沖突,所以,我們必須將transport-netty4-client的版本更新到6.3.2。
這就需要導入jar:org.elasticsearch.plugin----transport-netty4-client 的jar,(具體依賴將上面),這時候transport-netty4-client的版本也是6.3.2了。
2.2.3. 到這里已經可以使用elasticsearch的集群了,不過我們又導入了一個 elasticsearch-rest-high-level-client的jar,目的是:為了使用某些特殊的api。參見:https://www.cnblogs.com/ginb/p/8716485.html
3. 啟動項目,連接elasticSearch集群
3.1 配置集群信息
import org.elasticsearch.client.transport.TransportClient; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.common.transport.TransportAddress; import org.elasticsearch.transport.client.PreBuiltTransportClient; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import java.net.InetAddress; /** * @Auther: cc * @Date: * @Description: */ @Configuration public class ESConfig { private Logger logger = LoggerFactory.getLogger(this.getClass()); @Value("${elasticsearch.firstIp}") private String firstIp; @Value("${elasticsearch.secondIp}") private String secondIp; @Value("${elasticsearch.thirdIp}") private String thirdIp; @Value("${elasticsearch.firstPort}") private String firstPort; @Value("${elasticsearch.secondPort}") private String secondPort; @Value("${elasticsearch.thirdPort}") private String thirdPort; @Value("${elasticsearch.clusterName}") private String clusterName; @Bean public TransportClient getTransportClient() { logger.info("ElasticSearch初始化開始。。"); logger.info("要連接的節點1的ip是{},端口是{},集群名為{}" , firstIp , firstPort , clusterName); logger.info("要連接的節點2的ip是{},端口是{},集群名為{}" , secondIp , secondPort , clusterName); logger.info("要連接的節點3的ip是{},端口是{},集群名為{}" , thirdIp , thirdPort , clusterName); TransportClient transportClient = null; try { Settings settings = Settings.builder() .put("cluster.name",clusterName) //集群名稱 .put("client.transport.sniff",true) //目的是為了可以找到集群,嗅探機制開啟 .build(); transportClient = new PreBuiltTransportClient(settings); TransportAddress firstAddress = new TransportAddress(InetAddress.getByName(firstIp),Integer.parseInt(firstPort)); TransportAddress secondAddress = new TransportAddress(InetAddress.getByName(secondIp),Integer.parseInt(secondPort)); TransportAddress thirdAddress = new TransportAddress(InetAddress.getByName(thirdIp),Integer.parseInt(thirdPort)); transportClient.addTransportAddress(firstAddress); transportClient.addTransportAddress(secondAddress); transportClient.addTransportAddress(thirdAddress); logger.info("ElasticSearch初始化完成。。"); }catch (Exception e){ e.printStackTrace(); logger.error("ElasticSearch初始化失敗:" + e.getMessage(),e); } return transportClient; } }
對於上面代碼解釋:
3.1.1 首先需要再配置文件中配置服務器集群的所有ip,端口,然后通過@value導入到config類中。
3.2.2 類上必須加@Configuration注解,方法上必須加@Bean注解。
3.2 啟動項目,連接集群
啟動項目,如果不報錯就可行了。
4. 使用springboot操作索引
4.1 創建索引
主要使用方法:
CreateIndexRequest createIndexRequest = Requests.createIndexRequest(index).settings(settings).mapping(type,mapping); //指定setting,mapping創建索引,如果非結構化索引的話,不指定mapping CreateIndexResponse response = transportClient.admin().indices().create(createIndexRequest).get(); logger.info("建立索引映射成功:" + response.isAcknowledged());
4.2 刪除索引
DeleteIndexRequest deleteIndexRequest = Requests.deleteIndexRequest(index); //創建刪除索引的請求 DeleteIndexResponse response = transportClient.admin().indices().delete(deleteIndexRequest).get(); //刪除索引的響應 logger.info("刪除索引結果:{}",response.isAcknowledged());
完整代碼如下

import com.cc.es.domain.base.ResultBean; import io.swagger.annotations.Api; import io.swagger.annotations.ApiImplicitParam; import io.swagger.annotations.ApiImplicitParams; import io.swagger.annotations.ApiOperation; import org.apache.commons.lang3.StringUtils; 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.admin.indices.delete.DeleteIndexResponse; import org.elasticsearch.client.Requests; import org.elasticsearch.client.transport.TransportClient; import org.elasticsearch.common.xcontent.XContentBuilder; import org.elasticsearch.common.xcontent.XContentFactory; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; import javax.annotation.Resource; import java.util.*; /** * @Auther: Administrator * @Date: 2018/8/21 07 * @Description: */ @Api(value = "Index", tags = "索引") @RestController @RequestMapping("index") public class IndexController { private final String INDEX = "index"; private final String TYPE = "type"; private Logger logger = LoggerFactory.getLogger(this.getClass()); @Resource private TransportClient transportClient; @ApiOperation(value = "結構化創建索引") @ApiImplicitParams({ @ApiImplicitParam(name = "index", value = "索引名", required = true, dataType = "String", paramType = "query"), @ApiImplicitParam(name = "type", value = "類型", required = true, dataType = "Integer", paramType = "query"), @ApiImplicitParam(name = "fields", value = "結構化索引字段名,不定參數,傳入的時候參數名為索引字段名,值為對應的數據類型") }) @RequestMapping(value = "/create" , method = RequestMethod.POST) public ResultBean createIndex(@RequestParam Map<String,String> param){ ResultBean resultBean = new ResultBean(); String index = null; String type = null; List<String> fieldList = new ArrayList<>(); logger.info("接收的創建索引的參數:" + param); Set<Map.Entry<String, String>> set = param.entrySet(); for (Map.Entry<String, String> entry: set) { String key = entry.getKey(); if(key.trim().equals(INDEX)){ index = entry.getValue(); }else if(key.trim().equals(TYPE)){ type = entry.getValue(); }else{ fieldList.add(key); } } if(StringUtils.isBlank(index) || StringUtils.isBlank(type)){ resultBean.setSuccess(false); resultBean.setMsg("參數錯誤!"); return resultBean; } try { XContentBuilder settings = XContentFactory.jsonBuilder() .startObject() .field("number_of_shards",6) .field("number_of_replicas",1) .startObject("analysis").startObject("analyzer").startObject("ik") .field("tokenizer","ik_max_word") .endObject().endObject().endObject() .endObject(); XContentBuilder mapping = XContentFactory.jsonBuilder(); mapping.startObject().field("dynamic","strict").startObject("properties"); for (int i = 0,j = fieldList.size(); i < j; i++) { String field = fieldList.get(i); String fieldType = param.get(field); mapping.startObject(field).field("type",fieldType); if(fieldType.trim().equals("date")){ mapping.field("format","yyyy-MM-dd HH:mm:ss || yyyy-MM-dd "); } mapping.endObject(); } mapping.endObject().endObject(); CreateIndexRequest createIndexRequest = Requests.createIndexRequest(index).settings(settings).mapping(type,mapping); CreateIndexResponse response = transportClient.admin().indices().create(createIndexRequest).get(); logger.info("建立索引映射成功:" + response.isAcknowledged()); resultBean.setSuccess(true); resultBean.setMsg("創建索引成功!"); } catch (Exception e) { resultBean.setSuccess(false); resultBean.setMsg("創建索引失敗!"); logger.error("創建索引失敗!要創建的索引為{},文檔類型為{},異常為:",index,type,e.getMessage(),e); } return resultBean; } @ApiOperation(value = "刪除索引") @ApiImplicitParams({ @ApiImplicitParam(name = "index", value = "索引名", required = true, dataType = "String", paramType = "query"), }) @RequestMapping(value = "/delete" , method = RequestMethod.POST) public ResultBean deleteIndex(String index){ ResultBean resultBean = new ResultBean(); if (StringUtils.isBlank(index)) { resultBean.setMsg("參數錯誤,索引為空"); resultBean.setSuccess(false); return resultBean; } try { DeleteIndexRequest deleteIndexRequest = Requests.deleteIndexRequest(index); DeleteIndexResponse response = transportClient.admin().indices().delete(deleteIndexRequest).get(); logger.info("刪除索引結果:{}",response.isAcknowledged()); resultBean.setSuccess(response.isAcknowledged()); resultBean.setMsg(response.isAcknowledged() ? "刪除索引成功!" : "刪除索引失敗!"); } catch (Exception e) { resultBean.setSuccess(false); resultBean.setMsg("創建索引失敗!"); logger.error("刪除索引失敗!要刪除的索引為{},異常為:",index,e.getMessage(),e); } return resultBean; } }
到目前為止,springboot的索引已經完成。這里都是使用的原生的一些api,以后可能還會使用一些別的方法完成。