2021SC@SDUSC
搜索过程(2)
从之前分析的过程来看,IndexReader 有以下几个特性:
1.段元数据信息已经被读入到内存中,因而索引文件夹中因为新添加文档而新增加的段对
已经打开的reader 是不可见的。
2..del 文件已经读入内存,因而其他的reader 或者writer 删除的文档对打开的reader 也是
不可见的。
3.一个IndexReader 打开一个索引,
就好像对此索引照了一张像,无论背后索引如何改变,此IndexReader 在被重新打开之
前,看到的信息总是相同的。
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);
}