转载

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

一、项目介绍

最近一直在弄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;
    }
    
	@Override
	public void destroy() throws Exception {
		if(client!=null)
            client.close();
		
	}

	@Override
	public 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));		
	}

	@Override
	public TransportClient getObject() throws Exception {
		return client;
	}

	@Override
	public Class<?> getObjectType() {
		return TransportClient.class;
	}

	@Override
	public 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)})
@EnableTransactionManagement
public 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实现类中通过一下方式注入进来使用:

@Autowired
private TransportClient transportClient;

首页搜索页面如下所示

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

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

Elasticsearch系列(十一)----Spring整合Elasticsearch5.5.1的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;



@Service
public class CsdnBlogServiceImpl implements CsdnBlogService{

	@Autowired
	private 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(); 
	
	@Override
	public 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

原文  http://blog.csdn.net/u011781521/article/details/77891192
正文到此结束
Loading...