这章主要介绍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搜索索引
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;
}