1.前言
看本文前需要先对ElasticSearch有一定了解(比如什么是index 什么是type)
本人推荐直接使用ElasticSearch Java API来操作..本人最开始是用springboot spring-data-elasticsearch-starter 来作为orm的..操作是方便了很多.支持类spring-data-jpa的接口化查询..但是弊端太多.
1.更新非常慢.
2.文档非常少.
3.封装太多,不利于学习原生ElasticSearch
4.对于Springboot maven modules 项目来说..当更新ElasticSearch要更换parent的springboot 版本..
用spring-data-elasticsearch的话少了第四点.
2.开始搞事
1.加入依赖..(本例是基于Springboot + Maven..)
<dependency>
<groupId>org.elasticsearch</groupId> <artifactId>elasticsearch</artifactId> <version>5.5.0</version> </dependency>
<dependency> <groupId>org.elasticsearch.client</groupId> <artifactId>transport</artifactId> <version>5.5.0</version> </dependency> <!-- 没有使用X-Pack可以忽略下面依赖 --> <dependency> <groupId>org.elasticsearch.client</groupId> <artifactId>x-pack-transport</artifactId> <version>5.5.0</version> </dependency>
版本需要与你的ElasticSearch版本相同
ElasticsearchConfiguratio
package cn.youyinian.server; import org.elasticsearch.client.transport.TransportClient; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.common.transport.InetSocketTransportAddress; import org.elasticsearch.xpack.client.PreBuiltXPackTransportClient; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.DisposableBean; import org.springframework.beans.factory.FactoryBean; import org.springframework.beans.factory.InitializingBean; import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.Configuration; import java.net.InetAddress; import java.net.UnknownHostException; @Configuration public class ElasticsearchConfiguration implements FactoryBean<TransportClient>, InitializingBean, DisposableBean { private static final Logger logger = LoggerFactory.getLogger(ElasticsearchConfiguration.class); //由于项目从2.2.4配置的升级到 5.5.3版本 原配置文件不想动还是指定原来配置参数 @Value("${spring.data.elasticsearch.cluster-nodes}") private String clusterNodes ; @Value("${spring.data.elasticsearch.cluster-name}") private String clusterName; private TransportClient client; @Override public void destroy() throws Exception { try { logger.info("Closing elasticSearch client"); if (client != null) { client.close(); } } catch (final Exception e) { logger.error("Error closing ElasticSearch client: ", e); } } @Override public TransportClient getObject() throws Exception { return client; } @Override public Class<TransportClient> getObjectType() { return TransportClient.class; } @Override public boolean isSingleton() { return false; } @Override public void afterPropertiesSet() throws Exception { buildClient(); } protected void buildClient() { try { PreBuiltXPackTransportClient preBuiltXPackTransportClient = new PreBuiltXPackTransportClient(settings()); if (!"".equals(clusterNodes)){ for (String nodes:clusterNodes.split(",")) { String InetSocket [] = nodes.split(":"); String Address = InetSocket[0]; Integer port = Integer.valueOf(InetSocket[1]); preBuiltXPackTransportClient.addTransportAddress(new InetSocketTransportAddress(InetAddress.getByName(Address),port )); } client = preBuiltXPackTransportClient; } } catch (UnknownHostException e) { logger.error(e.getMessage()); } } /** * 初始化默认的client */ private Settings settings(){ Settings settings = Settings.builder() .put("cluster.name",clusterName) .put("xpack.security.transport.ssl.enabled", false) .put("xpack.security.user", "elastic:changeme") //xpack user配置 .put("client.transport.sniff", true).build(); return settings; } }
3.操作ElasticSearch
官方Java API 文档
本例是使用json字符串来插入
先注入client对象
public final TransportClient client; public TopicAuthSearchRemoteController(TransportClient client) { this.client = client; }
//加入索引
IndexResponse response = client.prepareIndex("index_topic", "topic_auth") .setSource(topicAuthJson, XContentType.JSON) .get();
//搜索 - 根据实体搜索
SearchResponse response = client.prepareSearch("index_topic")
.setTypes("topic_auth") .setQuery(QueryBuilders.termQuery("id", topicAuthId)) .get();
//删除索引
DeleteResponse deleteResponse = client.prepareDelete("index_topic", "topic_auth", id).get(); //重点:这里的id并不是实体的id..而是ElasticSearch每条记录都有的 _id 可以通过String id = response.getHits().getAt(0).getId(); 或者用API中得Delete by Queries
4.注意
你可以在过程中发现没有保存但是操作也没有成功. 因为ElasticSearch Java API TransportClient是异步的. 每一个请求都是一条线程. 并没有在主线程捕捉到Error. 所以应该在方法外面加个Try Catch... 如:
try { if(StringUtils.isEmpty(topicAuthJson)) { logger.info(topicAuthJson); IndexResponse response = client.prepareIndex("index_topic", "topic_auth") .setSource(topicAuthJson, XContentType.JSON) .get(); }else { logger.error("object add to index cannot be null"); } }catch (Exception e) { logger.error("error", e); }