2021SC@SDUSC
搜索过程(3)
Lucene搜索样例:
public static void main(String[] args)
{
try {
IndexReader reader=DirectoryReader.open(FSDirectory.open(new File("F:\\index")));
IndexSearcher searcher=new IndexSearcher(reader);
Analyzer analyzer=new StandardAnalyzer(Version.LUCENE_43);
QueryParser queryParser=new QueryParser(Version.LUCENE_43, "content", analyzer);
Query query=queryParser.parse("lucene");
TopDocs topDocs=searcher.search(query, 10);
ScoreDoc[] hits=topDocs.scoreDocs;
for(int i=0;i {
System.out.println("score:"+hits[i].score);
System.out.println("title:"+searcher.doc((hits[i].doc)).get("title"));
}
// reader.close();
} catch (Exception e) {
e.printStackTrace();
}
}
下面我们来分析IndexSearcher searcher=new IndexSearcher(reader)
IndexSearcher:
在一个单独的IndexReader上实现查找。 应用通常调用search(Query,int)或search(Query,Filter,int)
进行检索。 为了性能的考虑,如果你的索引是不变的,你应该为所有的查询应用一个单实例的IndexSearcher
而非每个查询创建一个实例。 如果你的索引已经改变,并且你希望检索时看到这些变化,你应该调用DirectoryReader的
openIfChanged(DirectoryReader)方法去重新获取reader,然后在该reader上创建一个新的IndexSearcher。
final IndexReader reader;
protected final IndexReaderContext readerContext;
protected final List leafContexts;
protected final LeafSlice[] leafSlices;
private final ExecutorService executor;
private static final Similarity defaultSimilarity = new DefaultSimilarity();
IndexSearcher 表面上看起来好像仅仅是reader 的一个封装,它的很多函数都是直接调用reader 的相应函数,如:int docFreq(Term term),Document doc(int i),int maxDoc()。
然而它提供了两个非常重要的函数:
1.void setSimilarity(Similarity similarity),用户可以实现自己的Similarity 对象,从而影响搜索过程的打分
2. 一系列search 函数,是搜索过程的关键,主要负责打分的计算和倒排表的合并。
因而在某些应用之中,只想得到某个词的倒排表的时候,最好不要用IndexSearcher,而直接
用IndexReader.termDocs(Term term),则省去了打分的计算。
IndexSeacher构造函数:
public IndexSearcher(IndexReaderContext context, ExecutorService executor) {
assert context.isTopLevel: "IndexSearcher's ReaderContext must be topLevel for reader" + context.reader();
reader = context.reader();
this.executor = executor;
this.readerContext = context;
leafContexts = context.leaves();
this.leafSlices = executor == null ? null : slices(leafContexts);
}