1. 程式人生 > >luence的java工具類,通用型別解析,支援資料庫

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);
	}
}