这章主要介绍IndexSearcher
IndexSearcher,一个我们用来搜索IndexWriter创建的索引的命令行程序。(记住我们的Seacher只是用来示范Lucene的搜索API的用法。你的搜索程序也可以是网页或带有GUI的桌面程序或EJB等形式。)
一下代码是从网上剪切过来的,可能有错误,但是原理都是一样的,明白了原理,什么都简单。稍后我会将我自己写的几个测试代码贴上去,可以 关注下后面的文字
MyIndexSearcher对IndexSearcher的创建和回收:
public class MyIndexSearcher { private static IndexSearcher indexSearcher; private static IndexReader indexReader; private static ArrayList<Thread> threadList = new ArrayList<Thread>(); private static Directory dir = null; private MyIndexSearcher() { } /** * * @function 创建IndexSearcher对象 * @param indexFilePath 索引路径 * @return */ public static IndexSearcher getInstance(String indexFilePath) { synchronized (threadList) { if (indexSearcher == null) { File indexFile = new File(indexFilePath); try { if (!indexFile.exists()) { indexFile.mkdirs(); } dir = FSDirectory.open(indexFile); // 读取索引的indexReader indexReader = IndexReader.open(dir); // 创建indexSearcher indexSearcher = new IndexSearcher(indexReader); } catch (IOException e) { e.printStackTrace(); } finally { indexFile=null; } } if (!threadList.contains(Thread.currentThread())) threadList.add(Thread.currentThread()); return indexSearcher; } } /** * * @function 关闭IndexSearcher对象 */ public static void close() { synchronized (threadList) { if (threadList.contains(Thread.currentThread())) threadList.remove(Thread.currentThread()); if (threadList.size() == 0) { try { if (indexReader != null) { indexReader.close(); indexReader = null; } if (indexSearcher != null) { indexSearcher.close(); indexSearcher = null; } if (dir != null) { dir.close(); } } catch (IOException e) { e.printStackTrace(); } } } } }
IndexSearcher用来搜索而IndexWriter用来索引:暴露几个搜索方法的索引的主要链接。你可以把IndexSearcher想象为以只读方式打开索引的一个类。它提供几个搜索方法,其中一些在抽象基类IndexSearcher中实现;最简单的接受单个Query对象做为参数并返回一个Hits对象。
/** * * @function 查询所有资源 * @param searchParam * 查询内容关键字 * @param pageNum 页码 * @param pageSize 每页显示大小 * @return */ public static List<SearchBean> getSearchBeanAll(String searchParam, int pageNum, int pageSize) throws Exception { // 庖丁解牛分词器 Analyzer analyzer = new PaodingAnalyzer(); // 对用户的输入进行查询 searcher = MyIndexSearcher.getInstance(FILE_PATH + ConfigurationManager.getInstance().getPropertiesValue( "common.properties", "AllIndexFilePath") + "/index"); // 对用户的输入进行查询 Query query = MultiFieldQueryParser.parse(Version.LUCENE_CURRENT, searchParam, new String[] { "title", "content", "url", "keyword", "time" }, new BooleanClause.Occur[] { BooleanClause.Occur.SHOULD, BooleanClause.Occur.SHOULD, BooleanClause.Occur.SHOULD, BooleanClause.Occur.SHOULD, BooleanClause.Occur.SHOULD }, analyzer); BooleanQuery bQuery = new BooleanQuery(); bQuery.add(query, BooleanClause.Occur.MUST); // 根据字段进行排序,得到查询结果 SortField sortField1 = new SortField("time", SortField.STRING, true);// false代表升序,TRUE代表降序 SortField sortField2 = new SortField("keyword", SortField.SCORE, false); SortField sortField3 = new SortField("title", SortField.SCORE, false); TopDocs topDocs = searcher.search(bQuery, null, 100000, new Sort( sortField3, sortField2, sortField1)); List<SearchBean> list = getSearchResult(analyzer, topDocs, bQuery, searchParam, pageNum, pageSize); // for (SearchBean searchBean : list) { // System.out.println(searchBean.toString()); // } return list; } /** * * @function 得到查询结果 * @param analyzer 分词器 * @param topDocs 搜索文档 * @param query 搜索对象 * @param searchParam 搜索内容关键字 * @param pageNum 页码 * @param pageSize 页显示数 * @return */ public static List<SearchBean> getSearchResult(Analyzer analyzer, TopDocs topDocs, Query query, String searchParam, int pageNum, int pageSize) throws Exception { FastVectorHighlighter highlighter = getHighlighter(); FieldQuery fieldQuery = highlighter.getFieldQuery(query); ScoreDoc[] scoreDocs = topDocs.scoreDocs; // 查询结果数量 num = topDocs.totalHits; // 创建list,将结果保存其中,以便在jsp页面中进行显示 List<SearchBean> list = new ArrayList<SearchBean>(); // 模拟hibernate的serFirstResult和setMaxResult以便返回指定条目的结果 int end = 0; int begin = 0; begin = pageSize * (pageNum - 1); if (begin > num) { begin = begin - pageSize + num % pageSize; } if (pageNum * pageSize > num) { end = num; } else end = pageNum * pageSize; // System.out.println(num + "/" + begin + "/" + end); try { for (int i = begin; i < end; i++) { String bestFragmentTitle = highlighter.getBestFragment( fieldQuery, searcher.getIndexReader(), scoreDocs[i].doc, "title", 50); String bestFragmentContent = highlighter.getBestFragment( fieldQuery, searcher.getIndexReader(), scoreDocs[i].doc, "content", 100); String bestFragmentKeyword = highlighter.getBestFragment( fieldQuery, searcher.getIndexReader(), scoreDocs[i].doc, "keyword", 100); String bestFragmentTime = highlighter.getBestFragment( fieldQuery, searcher.getIndexReader(), scoreDocs[i].doc, "time", 100); Document doc = searcher.doc(scoreDocs[i].doc); // 取得该条索引文档 SearchBean sb = new SearchBean(); String id = doc.get("id"); String title = doc.get("title"); String content = doc.get("content"); String url = doc.get("url"); String keyword = doc.get("keyword"); String time = doc.get("time"); String author = doc.get("author"); String module = doc.get("module"); String type = doc.get("type"); sb.setId(id); sb.setTitle((bestFragmentTitle != null && bestFragmentTitle != "") ? bestFragmentTitle: title); sb.setContent((bestFragmentContent != null && bestFragmentContent != "") ? bestFragmentContent: content); sb.setUrl(url); sb.setKeyword((bestFragmentKeyword != null && bestFragmentKeyword != "") ? bestFragmentKeyword: keyword); sb.setTime((bestFragmentTime != null && bestFragmentTime != "") ? bestFragmentTime: time); sb.setAuthor(author); sb.setModule(module); sb.setType(type); list.add(sb); } } catch (Exception e) { e.printStackTrace(); logger.error(e.getMessage()); } finally { MyIndexSearcher.close(); } return list; }