优化 IndexReader 的使用
下面的一个模式是我们经常使用的。
相对于索引的创建而言,索引的搜索是使用频繁的。所以 IndexReader 是会经常使用的,所以我们很自然地想到应该将 IndexReader 设计成一个单例模式。但是索引增加、修改、删除以后,IndexReader 须要重新读取索引信息,才能保证我们的索引信息是准确的,那有没有办法不用重新打开索引,就能保证我们的 IndexReader 是读取最新的索引呢?
有的 , 使用 DirectoryReader 类的静态方法 openIfChanged 就可以达到目的,这个判断会先判断索引是否变更,如果变更,我们要先把原来的 IndexReader 释放。下面的例子展示了 IndexReader 的使用过程。
/**
* 重用一些旧的 IndexReader
* @return
*/
public IndexSearcher getSearcher() {
try {
if(reader==null) {
reader = DirectoryReader.open(directory);
} else {
// 如果 IndexReader 不为空,就使用 DirectoryReader 打开一个索引变更过的 IndexReader 类
// 此时要记得把旧的索引对象关闭
// 参考资料:Lucene系列-近实时搜索(1)
// http://blog.csdn.net/whuqin/article/details/42922813
IndexReader tr = DirectoryReader.openIfChanged((DirectoryReader)reader);
if(tr!=null) {
reader.close();
reader = tr;
}
}
return new IndexSearcher(reader);
} catch (CorruptIndexException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
常用的搜索方法
下面归纳了一些常用的搜索方法,最后给出了整个搜索的测试例子,供大家参考。
1、TermQuery 搜索特定的项(上一节已经介绍过)
// 搜索特定的项
Query query = new TermQuery(new Term(field,value));
2、TermRangeQuery 搜索特定范围的项
这个 Query 不适用于数字范围查询,数字范围查询请使用 NumericRangeQuery 代替
Query query = new TermRangeQuery(field,new BytesRef(start.getBytes()),new BytesRef(end.getBytes()),true,true);
3、NumericRangeQuery 搜索数字范围的项
NumericRangeQuery<Integer> query = NumericRangeQuery.newIntRange(field,start,end,true,true);
4、PrefixQuery 前缀匹配搜索
Query query = new PrefixQuery(new Term(field,value));
5、WildcardQuery 通配符搜索
Query query = new WildcardQuery(new Term(field,value));
6、FuzzyQuery 模糊匹配搜索
模糊匹配的意思是:搜索的关键字即使有错,在一定范围内都可以被搜索到
FuzzyQuery query = new FuzzyQuery(new Term(field,value),maxEdits,prefixLength);
7、BooleanQuery 多个条件的查询
BooleanQuery.Builder booleanQuery = new BooleanQuery.Builder();
Query query1 = new TermQuery(new Term(field1,value1));
Query query2 = new TermQuery(new Term(field2,value2));
booleanQuery.add(query1,BooleanClause.Occur.MUST);
booleanQuery.add(query2,BooleanClause.Occur.MUST);
8、PhraseQuery 短语查询
PhraseQuery phraseQuery = new PhraseQuery();
phraseQuery.setSlop(slop);
phraseQuery.add(new Term(field,value1));
phraseQuery.add(new Term(field,value2));
9、QueryParser 方式的查询