Elasticsearch系列(十一)----Spring整合Elasticsearch5.5.1的TransportClient客户端

来源:互联网 发布:apache webservice 编辑:程序博客网 时间:2024/06/05 16:46
一、项目介绍


最近一直在弄Elasticsearch,所以学习了下Spring整合Elasticsearch的TransportClient客户端,使用的是spring提供的@Configuration注解来管理TransportClient客户端,具体如下:


TransportClient客户端配置实体类:

package com.fendo.config;import java.net.InetAddress;import org.elasticsearch.client.transport.TransportClient;import org.elasticsearch.common.settings.Settings;import org.elasticsearch.common.transport.InetSocketTransportAddress;import org.elasticsearch.transport.client.PreBuiltTransportClient;import org.springframework.beans.factory.DisposableBean;import org.springframework.beans.factory.FactoryBean;import org.springframework.beans.factory.InitializingBean;public class TransportClientFactory implements FactoryBean<TransportClient>,InitializingBean,DisposableBean{    private String clusterName;    private String host;    private int port;    private TransportClient client;            public void setClusterName(String clusterName) {        this.clusterName = clusterName;    }    public void setHost(String host) {        this.host = host;    }    public void setPort(int port) {        this.port = port;    }    @Overridepublic void destroy() throws Exception {if(client!=null)            client.close();}@Overridepublic void afterPropertiesSet() throws Exception {Settings settings=Settings.builder().put("cluster.name",this.clusterName).build();        client=new PreBuiltTransportClient(settings).addTransportAddress(new InetSocketTransportAddress(InetAddress.getByName(this.host),this.port));}@Overridepublic TransportClient getObject() throws Exception {return client;}@Overridepublic Class<?> getObjectType() {return TransportClient.class;}@Overridepublic boolean isSingleton() {return false;}}


TransportClient管理类:

package com.fendo.config;import java.util.LinkedHashSet;import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.ComponentScan;import org.springframework.context.annotation.Configuration;import org.springframework.context.annotation.FilterType;import org.springframework.stereotype.Controller;import org.springframework.transaction.annotation.EnableTransactionManagement;/** * @author fendo *  */@Configuration@ComponentScan(basePackages = {"com.fendo"},        excludeFilters = {@ComponentScan.Filter(type= FilterType.ANNOTATION,value = Controller.class)})@EnableTransactionManagementpublic class SpringConfiguration {    //bean的id为transportClient    @Bean    public TransportClientFactory transportClient(){    TransportClientFactory transportClientFactory=new TransportClientFactory();        transportClientFactory.setClusterName("my-application");        transportClientFactory.setHost("localhost");        transportClientFactory.setPort(9300);        return transportClientFactory;    }}

然后在Service实现类中通过一下方式注入进来使用:


@Autowiredprivate TransportClient transportClient;

首页搜索页面如下所示




能对搜索的关键字实现高亮显示





二、原理分析


实现代码如下,由于只是个简单的搜索,代码写得也是很简单。。。


package com.fendo.service.impl;import java.util.ArrayList;import java.util.List;import java.util.Map;import org.apache.log4j.Logger;import org.elasticsearch.action.search.SearchResponse;import org.elasticsearch.client.transport.TransportClient;import org.elasticsearch.common.text.Text;import org.elasticsearch.index.query.MatchAllQueryBuilder;import org.elasticsearch.index.query.QueryBuilder;import org.elasticsearch.index.query.QueryBuilders;import org.elasticsearch.index.query.QueryStringQueryBuilder;import org.elasticsearch.search.SearchHit;import org.elasticsearch.search.SearchHits;import org.elasticsearch.search.builder.SearchSourceBuilder;import org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder;import org.elasticsearch.search.fetch.subphase.highlight.HighlightField;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.stereotype.Service;import com.fasterxml.jackson.databind.ObjectMapper;import com.fendo.common.Page;import com.fendo.entity.CsdnBlog;import com.fendo.service.CsdnBlogService;import net.sf.json.JSONObject;@Servicepublic class CsdnBlogServiceImpl implements CsdnBlogService{@Autowiredprivate TransportClient transportClient;private static int num = 0;private static final String IndexName="csdnblog";private static final String TypeName="article";public static final Logger LOGGER = Logger.getLogger(CsdnBlogServiceImpl.class);private static ObjectMapper mapper = new ObjectMapper(); @Overridepublic Page search(String param,Integer pageSize,Integer pageNo,String type) throws Exception { QueryBuilder queryBuilders=null;  Page page=new Page(); param = null==param?"":param; pageNo = null==pageNo?1:pageNo; pageSize = null==pageSize?15:pageSize; page.setPageNo(pageNo); page.setPageSize(pageSize);  long start = System.currentTimeMillis(); HighlightBuilder hiBuilder=new HighlightBuilder().field("*").requireFieldMatch(false);           hiBuilder.preTags("<span style=\"color:red\">");           hiBuilder.postTags("</span>");              //查询所有 if("All".equals(type)){ if(!"".equals(param)&¶m!=null){ queryBuilders = QueryBuilders.queryStringQuery(param); //设置高亮显示// hiBuilder=new HighlightBuilder().field("*").requireFieldMatch(false);;  // hiBuilder.preTags("<span style=\"color:red\">");  // hiBuilder.postTags("</span>"); //搜索title和orperator和detail        //QueryStringQueryBuilder queryBuilder = new QueryStringQueryBuilder(param);        hiBuilder.field("titles").field("content");         }else{ queryBuilders = QueryBuilders.matchAllQuery(); } } //查询标题 if("title".equals(type)){ queryBuilders = QueryBuilders.fuzzyQuery("titles", param); hiBuilder.field("titles"); } //查询内容 if("content".equals(type)){ queryBuilders = QueryBuilders.fuzzyQuery("content", param); hiBuilder.field("content"); }  hiBuilder.fragmentSize(10000);//高亮内容长度 hiBuilder.requireFieldMatch(false); SearchResponse response = transportClient.prepareSearch(IndexName)                  .setQuery(queryBuilders)                  .setFrom((pageNo - 1) * pageSize)                   .setSize(pageSize)                .highlighter(hiBuilder)        //高亮字段前缀                .setExplain(true)// 设置是否按查询匹配度排序                .execute().actionGet();   SearchHits hits = response.getHits();  int total=(int) hits.getTotalHits();  page.setTotalRecord(total); //总记录数  int totalPage = total/pageSize; if(total % pageSize != 0){     totalPage += 1; }  page.setTotalPage(totalPage);//总页数  for (SearchHit searchHit : hits) {   Map source = searchHit.getSource();CsdnBlog entity = (CsdnBlog) JSONObject.toBean(JSONObject.fromObject(source) , CsdnBlog.class);        if(!"".equals(type)&&type!=null){        String json=searchHit.getSourceAsString();    CsdnBlog csdnblog=mapper.readValue(json,CsdnBlog.class);        //获取高亮域    Map<String,HighlightField> result=searchHit.getHighlightFields();         //查询标题 if("title".equals(type)){    //从高亮域中取得指定域HighlightField nameField=result.get("titles");//取得定于的高亮标签Text[] nameTexts=nameField.getFragments();    //为name串值增加自定义的高亮标签String titles="";for(Text text:nameTexts){titles+=text;}//将追加了高亮标签的串值重新填充到对应的对象entity.setTitles(titles); } //查询内容 if("content".equals(type)){    //从高亮域中取得指定域HighlightField nameField=result.get("content");//取得定于的高亮标签Text[] contentsTexts=nameField.getFragments();    //为name串值增加自定义的高亮标签String contents="";for(Text text:contentsTexts){contents+=text;}//将追加了高亮标签的串值重新填充到对应的对象entity.setContent(contents); }  //查询所有 if("All".equals(type)){    //从高亮域中取得指定域HighlightField titlesField=result.get("titles");if(titlesField!=null&&!"".equals(titlesField)){//取得定于的高亮标签Text[] nameTexts=titlesField.getFragments();    //为name串值增加自定义的高亮标签String titles="";for(Text text:nameTexts){titles+=text;}entity.setTitles(titles);}//从高亮域中取得指定域HighlightField contentField=result.get("content");if(!"".equals(contentField)&&contentField!=null){//取得定于的高亮标签Text[] contentsTexts=contentField.getFragments();//为name串值增加自定义的高亮标签String contents="";for(Text text:contentsTexts){contents+=text;}entity.setContent(contents);} }        }page.getSimpleResult().add(entity);} long end = System.currentTimeMillis();  SearchResponse responses = transportClient.prepareSearch(IndexName)                  .setQuery(QueryBuilders.matchAllQuery())                  .execute().actionGet();   SearchHits hi = responses.getHits();  int totals=(int) hi.getTotalHits();  page.setMessage("在" + totals + "条记录中,搜索("+param+"),共用时间 -->> " + (end - start) + " 毫秒"); System.out.println("在" + totals + "条记录中,搜索"+param+",共用时间 -->> " + (end - start) + " 毫秒"); return page;}}


所有的数据都是用webmagic爬虫进行爬取得,然后使用Logstash-input-jdbc同步数据库中的数据到ES,具体可参考我以前的文章。


完整项目: http://download.csdn.net/download/u011781521/9969651

Github地址: https://github.com/fendo8888/Spring_Elasticsearch5.5.1

阅读全文
0 0
原创粉丝点击