luence的java工具类,通用类型解析,支持数据库

最近在研究luence,根据实际情况写了一个简单的DEMO

功能满足以下要求:

1、支持不同对象的传入,创建索引和查询

2、支持索引字段的动态配置

3、支持索引结果的html处理


以下为工具类

package com.hellowin.luence;

import java.io.BufferedReader;
import java.io.File;
import java.io.InputStreamReader;
import java.io.StringReader;
import java.lang.reflect.Method;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.commons.beanutils.BeanUtils;
import org.apache.lucene.analysis.Analyzer;
import org.apache.lucene.analysis.TokenStream;
import org.apache.lucene.analysis.cn.ChineseAnalyzer;
import org.apache.lucene.analysis.standard.StandardAnalyzer;
import org.apache.lucene.document.Document;
import org.apache.lucene.document.Field;
import org.apache.lucene.document.TextField;
import org.apache.lucene.index.DirectoryReader;
import org.apache.lucene.index.IndexWriter;
import org.apache.lucene.index.IndexWriterConfig;
import org.apache.lucene.queryparser.classic.MultiFieldQueryParser;
import org.apache.lucene.search.IndexSearcher;
import org.apache.lucene.search.Query;
import org.apache.lucene.search.ScoreDoc;
import org.apache.lucene.search.TopDocs;
import org.apache.lucene.search.highlight.Highlighter;
import org.apache.lucene.search.highlight.QueryScorer;
import org.apache.lucene.search.highlight.SimpleFragmenter;
import org.apache.lucene.search.highlight.SimpleHTMLFormatter;
import org.apache.lucene.store.Directory;
import org.apache.lucene.store.SimpleFSDirectory;
import org.apache.lucene.util.Version;
import org.springframework.stereotype.Service;

import com.alibaba.fastjson.JSON;
import com.hellowin.mhc.util.property.PropertyUtil;

@Service("luenceManager")
public class LuenceManagerImpl implements ILuenceManager {
	//根据实际情况设置自己的根路径
	String path="C:\\index";
	/**
	 * list:需要存储到索引的数据集合,支持泛型
	 * respClassName:list的class类型
	 * multiFields:class对象中需要存储的属性名称
	 */
	public void createIndex(List<?> list,String respClassName,String[] multiFields) throws Exception {
		//根据class的类型创建索引文件保存路径
		File indexDir = new File(path+"\\"+respClassName);
		StandardAnalyzer luenceAnalyzer = new StandardAnalyzer(Version.LUCENE_4_9);
		IndexWriterConfig config = new IndexWriterConfig(Version.LUCENE_4_9,
				luenceAnalyzer);
		Directory directory = new SimpleFSDirectory(indexDir);
		IndexWriter indexWriter =   new  IndexWriter(directory, config); 
		//删除之前索引
		indexWriter.deleteAll();
		try{
			//如何multiFields为空,则通过反射获取class中所以属性做索引存储
			if(multiFields==null||multiFields.length==0){
				java.lang.reflect.Field[] flds = Class.forName(respClassName).getDeclaredFields();
				 multiFields = new String[flds.length];
				    if ( flds != null )
					    for ( int i = 0; i < flds.length; i++ )  
					    {  
					    	multiFields[i]=flds[i].getName();
					    }
			}
			//遍历list集合,将集合中的数据保存到document中
			for(Object obj:list){
				Document document =   new  Document(); 
			    for ( int i = 0; i < multiFields.length; i++ )  
			    {  
			    	String name =multiFields[i];
			        Method m = Class.forName(respClassName).getMethod("get"+name.substring(0,1).toUpperCase()+name.substring(1));
					String value= m.invoke(obj)!=null?m.invoke(obj).toString():"";
			        //如果是文件形式的内容,读取对应的内容信息
					//TODO:其他文件类型根据实际情况扩展
					if(value.endsWith(".html")){
			        	value = methodPa(PropertyUtil.getProperty("image.server.path")+value);
			        }
					Field field =new Field(name, value!=null?value:"", TextField.TYPE_STORED);
					document.add(field);   
			    }  
				indexWriter.addDocument(document); 
			}
		}catch (Exception e) {
			e.printStackTrace();
		}
		indexWriter.close();   
	}
	public String methodPa(String strURL){  
        String temp;  
        try{  
        	StringBuffer body = new StringBuffer();
        	int i=0;
            URL url = new URL(strURL);  
            HttpURLConnection conn = (HttpURLConnection)url.openConnection();  
            InputStreamReader isr = new InputStreamReader(conn.getInputStream(),"utf-8");  
            BufferedReader br = new BufferedReader(isr);  
            while((temp = br.readLine()) != null){  
            	body.append(temp);
            	i++;
            }     
            br.close();  
            isr.close();  
            return body.toString();
        }catch(Exception e){  
//            e.printStackTrace();  
        }  
        return null;
    }
	/**
	 * queryStr:索引的关键字段
	 * respClassName:list的class类型
	 * multiFields:需要索引的对应字段
	 * pagesize:一次查询多少
	 * spanFlag:是否需要对索引结果做处理
	 */
	public List<Object> getResult(String queryStr,String respClassName,String[] multiFields,int pagesize,Boolean spanFlag) throws Exception {
		List<Object> objList = new ArrayList<Object>();
		File indexDir = new File(path+"\\"+respClassName);
	    Directory directory = new SimpleFSDirectory(indexDir);
	    Analyzer analyzer = new ChineseAnalyzer();
	    DirectoryReader ireader = DirectoryReader.open(directory);
		IndexSearcher isearcher = new IndexSearcher(ireader);
		if(multiFields==null||multiFields.length==0){
			java.lang.reflect.Field[] flds = Class.forName(respClassName).getDeclaredFields();
			 multiFields = new String[flds.length];
			    if ( flds != null )
				    for ( int i = 0; i < flds.length; i++ )  
				    {  
				    	multiFields[i]=flds[i].getName();
				    }
		}
		MultiFieldQueryParser parser = new MultiFieldQueryParser(
				Version.LUCENE_4_9, multiFields, analyzer);
		// 设定具体的搜索词
		Query query = parser.parse(queryStr);
		TopDocs docs =isearcher.search(query,null, pagesize!=0?pagesize:10);//查找
		ScoreDoc[] hits = docs.scoreDocs;
		for (int i = 0; i < hits.length; i++) {
			Document hitDoc = isearcher.doc(hits[i].doc);
			Object obj = Class.forName(respClassName).newInstance();
			if ( multiFields != null )
			    for ( int j = 0; j < multiFields.length; j++ )  
			    {  
			    	String vaule=hitDoc.get(multiFields[j]);
			    	//判断如果需要对索引格式化
			    	if(spanFlag){
			    		SimpleHTMLFormatter simpleHTMLFormatter = new SimpleHTMLFormatter("<span style=\"color:red\">", "</span>");
			    		Highlighter highlighter = new Highlighter(simpleHTMLFormatter, new QueryScorer(query));
			            //设置高亮附近的字数  
			            highlighter.setTextFragmenter(new SimpleFragmenter(100));  
			            TokenStream tokenStream = analyzer.tokenStream(vaule, new StringReader(vaule));    
			            vaule = highlighter.getBestFragment(tokenStream, vaule);
			    	}
			    	BeanUtils.setProperty(obj, multiFields[j], vaule);
			    }
			objList.add(obj);
		}
		return objList;
	}  
}
以下为调用实例

package com.hellowin.controller;

import java.util.List;

import javax.servlet.http.HttpServletRequest;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.RequestMapping;

import com.alibaba.fastjson.JSON;
import com.hellowin.datadictionary.EnumBool;
import com.hellowin.imp.device.dao.INoticeDAO;
import com.hellowin.imp.device.model.Notice;
import com.hellowin.imp.device.model.NoticeExample;
import com.hellowin.luence.ILuenceManager;

@Controller
@RequestMapping("/luence")
public class LuenceController {
	@Autowired
	private INoticeDAO noticeDAO;
	@Autowired
	private ILuenceManager luenceManager ;
	private String[] multiFields ={"noticeTitle","noticeId","noticeBody"};
	@RequestMapping("/index")
	public String index(ModelMap modelMap, HttpServletRequest request) throws Exception{
		NoticeExample example = new NoticeExample();
		example.createCriteria().andStatusEqualTo(EnumBool.NO.getCode());
		List<Notice> list = noticeDAO.selectByExample(example);
		luenceManager.createIndex(list, Notice.class.getName(),multiFields);
		return "luence";
	}
	@RequestMapping("/search")
	public void search(ModelMap modelMap, HttpServletRequest request,String searchkey) throws Exception{
		searchkey="特朗普";
		List<Object> list = luenceManager.getResult(searchkey, Notice.class.getName(),multiFields, 10,true);
		modelMap.addAttribute("list", list);
	}
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值