版权声明:本文为博主原创文章,未经博主允许不得转载。
现在给大家分享一下Elasticsearch在Java项目中的应用方法。至于Elasticsearch服务安装的过程我们就不在详细的介绍了,详情参考Elasticsearch安装教程。此次我们就以Elasticsearch6.3.2为例。
1、在pom.xml文件引入Elasticsearch的相关jar包,相关jar包如下所示。
org.elasticsearch
elasticsearch
6.3.2
org.elasticsearch.client
transport
6.3.2
org.elasticsearch.client
elasticsearch-rest-high-level-client
6.3.2
2、编写Elasticsearch服务配置文件elasticsearch.properties,以便于调用elasticsearch服务。配置如下所示。
cluster.name=elasticsearch
client.transport.sniff=true
client.transport.ignore_cluster_name=true
server.ip=127.0.0.1
server.port=9300
server.portt=9200
postRequestIp =http://127.0.0.1:9200
3、注入Elasticsearch服务,具体代码如下所示:
import org.apache.http.HttpHost;
import org.elasticsearch.client.RestClient;
import org.elasticsearch.client.RestHighLevelClient;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.InitializingBean;
public class ESClientDecorator implements InitializingBean, DisposableBean {
private RestHighLevelClient restHighLevelClient;
private HttpHost httpHost;
public ESClientDecorator(HttpHost httpHost) {
this.httpHost = httpHost;
}
public RestHighLevelClient getRestHighLevelClient() {
if (restHighLevelClient == null) {
restHighLevelClient = new RestHighLevelClient(RestClient.builder(httpHost));
}
return restHighLevelClient;
}
@Override
public void destroy() throws Exception {
restHighLevelClient.close();
}
@Override
public void afterPropertiesSet() throws Exception {
restHighLevelClient = new RestHighLevelClient(RestClient.builder(httpHost));
}
}
import java.net.InetAddress;
import java.net.UnknownHostException;
import org.apache.http.HttpHost;
import org.elasticsearch.client.RestHighLevelClient;
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.jeecgframework.core.util.PropertiesUtil2;
import org.springframework.beans.factory.annotation.Autowire;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Scope;
@Configuration
public class ElasticsConfig {
/**
* 初始化
*/
@Bean(autowire = Autowire.BY_NAME, name = "restHighLevelClient")
public RestHighLevelClient restHighLevelClient() {
return getEsClientDecorator().getRestHighLevelClient();
}
/**
* 初始化
*/
@Bean(autowire = Autowire.BY_NAME, name = "client")
public TransportClient transportClient() {
PropertiesUtil2 properties = new PropertiesUtil2("elasticsearch.properties");
String clusterName=properties.readProperty("cluster.name");
String clientTransportSniff=properties.readProperty("client.transport.sniff");
String clientTransportIgnoreClusterName=properties.readProperty("client.transport.ignore_cluster_name");
String serverIp=properties.readProperty("server.ip");
String serverPort=properties.readProperty("server.port");
TransportClient client=null;
Settings esSettings = Settings.builder()
.put("cluster.name", clusterName) //设置ES实例的名称
.put("client.transport.sniff",Boolean.parseBoolean(clientTransportSniff)) //自动嗅探整个集群的状态,把集群中其他ES节点的ip添加到本地的客户端列表中
.put("client.transport.ignore_cluster_name", Boolean.parseBoolean(clientTransportIgnoreClusterName)) //如果集群名不对,也能连接
.build();
client = new PreBuiltTransportClient(esSettings);//初始化client较老版本发生了变化,此方法有几个重载方法,初始化插件等。 //此步骤添加IP,至少一个,其实一个就够了,因为添加了自动嗅探配置
try {
client.addTransportAddress(new TransportAddress(InetAddress.getByName(serverIp), Integer.parseInt(serverPort)));
} catch (UnknownHostException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return client;
}
@Bean
@Scope("singleton")
public ESClientDecorator getEsClientDecorator() {
PropertiesUtil2 properties = new PropertiesUtil2("elasticsearch.properties");
String serverIp=properties.readProperty("server.ip");
String serverPort=properties.readProperty("server.portt");
//可以配置集群 通过逗号隔开
return new ESClientDecorator(new HttpHost(serverIp,Integer.parseInt(serverPort)));
}
}
4、具体应用实例。
控制层代码如下所示
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import javax.servlet.http.HttpServletRequest;
import org.apache.commons.lang3.StringUtils;
import org.elasticsearch.action.ActionFuture;
import org.elasticsearch.action.admin.indices.delete.DeleteIndexResponse;
import org.elasticsearch.action.admin.indices.exists.types.TypesExistsRequestBuilder;
import org.elasticsearch.action.admin.indices.exists.types.TypesExistsResponse;
import org.elasticsearch.action.admin.indices.get.GetIndexResponse;
import org.elasticsearch.action.admin.indices.stats.IndexStats;
import org.elasticsearch.action.admin.indices.stats.IndicesStatsRequest;
import org.elasticsearch.action.admin.indices.stats.IndicesStatsResponse;
import org.elasticsearch.action.bulk.BulkRequestBuilder;
import org.elasticsearch.action.index.IndexResponse;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.client.IndicesAdminClient;
import org.elasticsearch.client.transport.TransportClient;
import org.elasticsearch.index.query.MatchPhraseQueryBuilder;
import org.elasticsearch.index.query.QueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder;
import org.elasticsearch.search.sort.SortOrder;
import org.hibernate.validator.xml.GetterType;
import org.jeecgframework.core.common.controller.BaseController;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.ModelAndView;
import elasticsearch.entity.FmsUserDto;
import elasticsearch.service.ISearchClientServiceI;
import elasticsearch.utils.DateUtils;
/**
*
* @since 2018-12-19
* @author wudw
* @version V1.0
*/
@Controller
@RequestMapping("/testLocalController")
public class TestLocalController extends BaseController {
private final Logger LOG = LoggerFactory.getLogger(TestLocalController.class);
@Autowired
private ISearchClientServiceI iSearchClient;
@Autowired
private TransportClient tclient;
@RequestMapping(params = "list")
public ModelAndView list(Integer pageIndex,Integer limit,String doctitle,HttpServletRequest re) {
System.out.println("---------------变了-----------------");
//删除整个索引库。
//DeleteIndexResponse dResponse = tclient.admin().indices().prepareDelete("edu_operate_search")
// .execute().actionGet();
GetIndexResponse resp = tclient.admin().indices().prepareGetIndex().execute().actionGet();
ActionFuture isr = tclient.admin().indices().stats(new IndicesStatsRequest().indices("edu_operate_search_analysis"));
IndicesAdminClient indicesAdminClient = tclient.admin().indices();
Map indexStatsMap = isr.actionGet().getIndices();
Set set = isr.actionGet().getIndices().keySet();
return new ModelAndView("elasticsearch/elasticsearchList");
}
public static String checkChinese(String str){
String sb = new String();
Pattern pattern = Pattern.compile("[\u3007\u4E00-\u9FCB\uE815-\uE864]");
//只匹配一个中文字符
Matcher matcher = pattern.matcher(str);
while(matcher.find()){
sb += matcher.group()+";";
}
return sb.toString();
}
@RequestMapping("/testEs")
@ResponseBody
public void testEs() throws Exception {
//插入数据
for(int i=11;i<20;i++){
FmsUserDto user = new FmsUserDto();
//user.setName("es测试数据名称"+i);
//user.setCompanyname("测试企业"+i);
user.setId(i);
IndexResponse indexResponse = iSearchClient.saveEntity("mytest", "testBean", i+"",user );
//System.out.println(indexResponse.toString());
}
//es查询
SearchRequest request =new SearchRequest();
//数据库名称
request.indices("mytest");
//表名
request.types("testBean");
SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
sourceBuilder.query(QueryBuilders.matchQuery("name", "数据"))
.query(QueryBuilders.matchQuery("companyname", "开心"));
//设置排序
sourceBuilder.sort("id",SortOrder.DESC);
//设置分页
sourceBuilder.from(0);
sourceBuilder.size(5);
request.source(sourceBuilder);
List users = iSearchClient.search(request, FmsUserDto.class);
//System.out.println("user :"+users.toString());
}
@RequestMapping("/testMoreEs")
@ResponseBody
public void testMoreEs() throws Exception {
//多条件设置
SearchRequest request =new SearchRequest();
request.indices("mytest");
request.types("testBean");
MatchPhraseQueryBuilder mpq1 = QueryBuilders.matchPhraseQuery("name","数据");
MatchPhraseQueryBuilder mpq2 = QueryBuilders.matchPhraseQuery("companyname","企业");
QueryBuilder qb2 = QueryBuilders.boolQuery().must(mpq1).must(mpq2);
SearchSourceBuilder sourceBuilderm = new SearchSourceBuilder();
sourceBuilderm.query(qb2);
sourceBuilderm.sort("id",SortOrder.DESC);
sourceBuilderm.from(0);
sourceBuilderm.size(5);
request.source(sourceBuilderm);
List users = iSearchClient.search(request, FmsUserDto.class);
//System.out.println("user :"+users.toString());
}
}
service层的代码如下所示:
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.google.gson.Gson;
import elasticsearch.service.ISearchClientServiceI;
import elasticsearch.utils.DateUtils;
import elasticsearch.utils.sendRequestUtil;
import org.apache.commons.lang3.StringUtils;
import org.elasticsearch.action.admin.indices.close.CloseIndexResponse;
import org.elasticsearch.action.admin.indices.create.CreateIndexResponse;
import org.elasticsearch.action.admin.indices.delete.DeleteIndexResponse;
import org.elasticsearch.action.admin.indices.exists.indices.IndicesExistsRequest;
import org.elasticsearch.action.admin.indices.exists.indices.IndicesExistsResponse;
import org.elasticsearch.action.admin.indices.exists.types.TypesExistsRequest;
import org.elasticsearch.action.admin.indices.exists.types.TypesExistsResponse;
import org.elasticsearch.action.admin.indices.open.OpenIndexResponse;
import org.elasticsearch.action.bulk.BulkRequestBuilder;
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.client.IndicesAdminClient;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.client.transport.TransportClient;
import org.elasticsearch.cluster.ClusterState;
import org.elasticsearch.cluster.metadata.IndexMetaData;
import org.elasticsearch.cluster.metadata.MappingMetaData;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.xcontent.XContentType;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.SearchHits;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder;
import org.jeecgframework.core.common.service.impl.CommonServiceImpl;
import org.jeecgframework.core.util.PropertiesUtil;
import org.jeecgframework.core.util.ResourceUtil;
import org.jeecgframework.core.util.UUIDGenerator;
import org.jeecgframework.web.system.pojo.base.TSUser;
import org.springframework.beans.factory.annotation.Autowired;
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;
import java.util.Set;
/**
*
* @author wudw
* @date 2018-12-18 15:00:00
* @version 1.0
*/
@Service("searchClientService")
public class EsSearchClientServiceImpl extends CommonServiceImpl implements ISearchClientServiceI {
@Autowired
private RestHighLevelClient client;
@Autowired
private TransportClient tclient;
@Override
public List search(SearchRequest request) {
try {
SearchResponse response = (SearchResponse) client.search(request);
if (response.getHits() == null) {
return null;
}
List list = new ArrayList<>();
response.getHits().forEach(item -> list.add(JSON.parseObject(item.getSourceAsString())));
return list;
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
@Override
public List searchString(SearchRequest request) {
try {
SearchResponse response = (SearchResponse) client.search(request);
if (response.getHits() == null) {
return null;
}
List list = new ArrayList<>();
response.getHits().forEach(item -> list.add(item.getSourceAsString()));
return list;
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
@Override
public List search(SearchRequest request, Class tClass) {
List searchResponse = this.search(request);
if (searchResponse == null) {
return null;
}
List list = new ArrayList<>(searchResponse.size());
searchResponse.forEach(item -> list.add(JSON.parseObject(JSON.toJSONString(item), tClass)));
return list;
}
@Override
public IndexResponse saveEntity(String index, String type, String id, T t) {
IndexResponse indexResponse = null;
IndexRequest indexRequest = new IndexRequest(index, type , id);
indexRequest.source(JSON.toJSONString(t) , XContentType.JSON);
try {
indexResponse = (IndexResponse) this.client.index(indexRequest);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return indexResponse;
}
@Override
public DeleteResponse deldata(String index, String type, String id) {
// TODO Auto-generated method stub
DeleteResponse response=tclient.prepareDelete(index,type,id).get();
return response;
}
/**
* 删除整个索引库,慎用。
* @param index 数据库名称
* @return
*/
@Override
public DeleteIndexResponse delIndex(String index) {
// TODO Auto-generated method stub
DeleteIndexResponse dResponse = tclient.admin().indices().prepareDelete(index)
.execute().actionGet();
return dResponse;
}
@Override
public long searchtotal(SearchRequest request) {
// TODO Auto-generated method stub
SearchResponse response;
long total=0;
try {
response = (SearchResponse) client.search(request);
SearchHits hits = response.getHits();
total= hits.getTotalHits();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return total;
}
@Override
public boolean createIndex(String indexName) {
// TODO Auto-generated method stub
IndicesAdminClient indicesAdminClient = tclient.admin()
.indices();
CreateIndexResponse response = indicesAdminClient.prepareCreate(
indexName).get();
return response.isAcknowledged();
}
@Override
public boolean createIndex(String indexName, String indexType, String mappingSource) {
// TODO Auto-generated method stub
if (isExistsIndex(indexName)) {
return false;
}
// setting
Settings settings = Settings.builder().put("index.number_of_shards", 3)
.put("index.number_of_replicas", 2).build();
// mapping
IndicesAdminClient indicesAdminClient = tclient.admin()
.indices();
CreateIndexResponse response = indicesAdminClient
.prepareCreate(indexName).setSettings(settings)// setting
.addMapping(indexType, mappingSource)// type,mapping
.get();
return response.isAcknowledged();
}
/**
* 判断索引是否存在
* @param indexName:索引名
* @return
*/
public boolean isExistsIndex(String indexName) {
// TODO Auto-generated method stub
IndicesExistsResponse response = tclient
.admin()
.indices()
.exists(new IndicesExistsRequest()
.indices(new String[] { indexName })).actionGet();
return response.isExists();
}
/**
* 判断指定的索引的类型是否存在
* @param indexName:索引名
* @param indexType:索引类型
* @return 存在:true; 不存在:false;
*/
public boolean isExistsType(String indexName, String indexType) {
// TODO Auto-generated method stub
TypesExistsResponse response = tclient
.admin()
.indices()
.typesExists(
new TypesExistsRequest(new String[] { indexName },
indexType)).actionGet();
return response.isExists();
}
/**
* 删除索引
* @param indexName:索引名
* @return
*/
public boolean deleteIndex(String indexName) {
// TODO Auto-generated method stub
IndicesAdminClient indicesAdminClient = tclient.admin()
.indices();
DeleteIndexResponse response = indicesAdminClient
.prepareDelete(indexName).execute().actionGet();
return response.isAcknowledged();
}
/**
* 关闭索引
* @param index
* @return
*/
public boolean closeIndex(String index) {
// TODO Auto-generated method stub
IndicesAdminClient indicesAdminClient = tclient.admin()
.indices();
CloseIndexResponse response = indicesAdminClient.prepareClose(index)
.get();
return response.isAcknowledged();
}
/**
* 打开索引
* @param index
* @return
*/
public boolean openIndex(String index) {
// TODO Auto-generated method stub
IndicesAdminClient indicesAdminClient = tclient.admin()
.indices();
OpenIndexResponse response = indicesAdminClient.prepareOpen(index)
.get();
return response.isAcknowledged();
}
/**
* 数据同步
* @param indexName:索引名称
* @param indexType:索引类型
* @param databaseTable:数据库表
* @param field:字段名称
* @return
*/
public long synchData(String indexName, String indexType, String databaseTable,String allSql,String whereSql) {
// TODO Auto-generated method stub
System.out.println("数据更新开始!!!!=="+DateUtils.getDate("yyyy-MM-dd HH:mm:ss"));
long total=this.getCountForJdbc("select count(id) from "+databaseTable+" "+whereSql);
if(total==0){
return 0;
}
long prop=total%100000!=0?total/100000+1:total/100000;
for (int j = 0; j > listu=this.findForJdbc(allSql+" limit "+(j*100000)+",100000 ");
try {
BulkRequestBuilder bulkRequest =tclient.prepareBulk();
for (int i = 0; i < listu.size(); i++) {
bulkRequest.add(tclient.prepareIndex(indexName,indexType,listu.get(i).get("id").toString()).setSource(listu.get(i)).request());
//每10000条提交一次
if (i!=0 && (i % 10000 == 0||i==listu.size()-1)) {
bulkRequest.execute().actionGet(); //此处新建一个bulkRequest,类似于重置效果 bulkRequest =
tclient.prepareBulk();
}
}
synchDatarecordSave(indexName, indexType, databaseTable, allSql, total);
System.out.println("数据更新中!!!!==****"+listu.size()+DateUtils.getDate("yyyy-MM-dd HH:mm:ss"));
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
return -1;
}
}
System.out.println("数据更新完毕!!!!=="+DateUtils.getDate("yyyy-MM-dd HH:mm:ss"));
return total;
}
public void synchDatarecordSave(String indexName, String indexType, String databaseTable,String allSql,long total) {
TSUser user = ResourceUtil.getSessionUser();
String nodate=DateUtils.getDate("yyyy-MM-dd HH:mm:ss");
this.executeSql("insert into edu_synch_record values(?,?,?,?,?,?,?,?)",UUIDGenerator.generate(),databaseTable,indexName,indexType,allSql,total,user.getUserName(),nodate);
this.executeSql(" update edu_synch_table set state=1 where tab_code=? ",databaseTable);
}
@Override
public List