现在的位置: 首页 > 综合 > 正文

TermQuery & FilterQuery

2012年09月04日 ⁄ 综合 ⁄ 共 1786字 ⁄ 字号 评论关闭

TermQuery rewrite=this “wdx”
1. getWeight过程
实例化一个TermWeight,其属性如下
float value - idf * idf * boost / Math.sqrt(idf * boost * idf * boost)
float idf - term在index中的IDF
float queryNorm - 1.0 / Math.sqrt(idf * boost * idf * boost)
float queryWeight - idf * boost / Math.sqrt(idf * boost * idf * boost)
--------------------------------------------
2. 构造TermScorer.scorer的过程
a. 获取这个TERM的TermDocs,获取这个TERM出现在哪些文档里面,以及出现的频率
b. 获取这个域下此IndexReader包含的DOC的NORM
c. 将a. b得到的数据用来实例化一个TermScorer
--------------------------------------------
3. 接下来由scorer.score(collector)驱动完成,TermScorer自己实现了score(collector),同时实现了
DocIdSetIterator对象的nextDoc,docID,advance函数
a. nextDoc函数
TermScorer读取TermDocs不是一个一个读的,使用了TermDocs的read函数,预先读32个DOCID&FREQ
放入缓冲区中,在每次调用nextDoc时先看缓冲区没初始化或者缓冲区的数据用完了,则会用read来填补
缓冲区,缓冲区有个游标pointer,每次填补缓冲区后游标归0;如果缓冲区里有数据则游标右移,将当前
DOCID&FREQ写到全局变量doc&freq变量上
b. doc函数 返回全局变量doc
c. score函数 计算当前DOC的分数
TermScorer会事先算好FREQ在[1-32]的DOC的除了NORM的分数,因为NORM的跟每个文档有关系的数据
这样每次计算当前文档的分数时,如果FREQ在[1-32]范围内直接到这个数组里面取....
具体算分数的公式是
weight.value * Math.sqrt(freq) * norm[docid]
-> Math.sqrt(freq) * norm[docid] * idf * idf * boost / Math.sqrt(idf * boost * idf * boost)
d. score(collector)函数
和nextDoc做法差不多,nextDoc是每次只取一个DOC,score(collector)是一次性将所有的DOCID给collector
循环调用read,将读取到的DOCID给collector...

--------------------------------------------

FilterQuery
FilterQuery - {query, filter} rewrite={query.rewrite, filter}
FilterQuery的Weight的一个匿名类,在构造Weight内部是获取query的Weight&Similarity
然后在匿名类里实现Weight的抽象函数
-sumOfSquaredWeights 调用query.weight.sumOfSquaredWeights*boost*boost
-normalize 调用query.weight.normalize
-getValue 返回query.weight.getValue * boost
- score 返回一个匿名Scorer,其实现为
先调用query.weight.scorer拿到原始query的scorer,然后再拿到filter.getDocIdSet
如果取得的DocIdSet或者DocIdSetIterator为null则返回null
-nextDoc函数,比较两个DOCID流{query.scorer的docId流,filer.docSetIterator流}
一旦两个DOCID流当前的DOCID一致则是当前的doc
-advance函数,同上区别是两个流先根据参数里的DOCID定位,再进行上面的逻辑
-scorer函数 - 返回scorer.score * boost 

抱歉!评论已关闭.