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..)
版本需要与你的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
@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
@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); }