luence的java工具類,通用型別解析,支援資料庫
阿新 • • 發佈:2019-02-05
最近在研究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); } }