注册 登录  
 加关注
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

Koala++'s blog

计算广告学 RTB

 
 
 

日志

 
 

IR——Boolean retrieval [OR和NOT查询]  

2010-02-04 15:10:15|  分类: 搜索引擎 |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |

         关于OR查询,Introduction to IR,没有怎么介绍。

public DisjunctionSumScorer(List<Scorer> subScorers, int minimumNrMatchers) throws IOException {

    super(null);

 

    nrScorers = subScorers.size();

 

    this.minimumNrMatchers = minimumNrMatchers;

    this.subScorers = subScorers;

 

    initScorerDocQueue();

}

         Nrnot required的缩写,minimumNrMatchers是最少匹配几个,initScorerDocQueue如下:

private void initScorerDocQueue() throws IOException {

    scorerDocQueue = new ScorerDocQueue(nrScorers);

    for (Scorer se : subScorers) {

       if (se.nextDoc() != NO_MORE_DOCS) {

           scorerDocQueue.insert(se);

       }

    }

}

         把这些scorers放到scorerDocQuere这个队列中去,这个是个优先对列,scorer的第一个文档id小的scorer排到前面。

public int nextDoc() throws IOException {

    if (scorerDocQueue.size() < minimumNrMatchers

    || !advanceAfterCurrent()) {

       currentDoc = NO_MORE_DOCS;

    }

    return currentDoc;

}  

若当前scorerDocQueue.size()小于minimumNrMatchers说明:scorers数量都比最小要达到的要少,这个就不太可能了。

protected boolean advanceAfterCurrent() throws IOException {

    do { // repeat until minimum nr of matchers

       currentDoc = scorerDocQueue.topDoc();

       currentScore = scorerDocQueue.topScore();

       nrMatchers = 1;

       do { // Until all subscorers are after currentDoc

           if (!scorerDocQueue.topNextAndAdjustElsePop()) {

              if (scorerDocQueue.size() == 0) {

                  break; // nothing more to advance, check for last match.

              }

           }

           if (scorerDocQueue.topDoc() != currentDoc) {

              break; // All remaining subscorers are after currentDoc.

           }

           currentScore += scorerDocQueue.topScore();

           nrMatchers++;

       } while (true);

 

       if (nrMatchers >= minimumNrMatchers) {

           return true;

       } else if (scorerDocQueue.size() < minimumNrMatchers) {

           return false;

       }

    } while (true);

}

         这个是要找到达到minimum nr的文档,内层的do/while循环,要让scorer的第一个doc都是currentDoc数量要等于nrMatchers

         还有一个是MUST NOT查询,如果只有一个词为MUST NOT,那就排除好了,但如果有多个呢,其实它是用了OR(DisjunctionSumScorer)来先得到一个scorer的。代码如下:

private Scorer addProhibitedScorers(Scorer requiredCountingSumScorer)

    throws IOException {

    return (prohibitedScorers.size() == 0) ? requiredCountingSumScorer

           : new ReqExclScorer(requiredCountingSumScorer,

              ((prohibitedScorers.size() == 1)

                  ? prohibitedScorers.get(0)

                  : new DisjunctionSumScorer(

                     prohibitedScorers)));

}

下面看ReqExclScorer

public ReqExclScorer(Scorer reqScorer, DocIdSetIterator exclDisi) {

    super(null); // No similarity used.

    this.reqScorer = reqScorer;

    this.exclDisi = exclDisi;

}

         reqScorer当然就是MUSTscorer,而exclDisi就是要被排除的文档iterator

再看nextDoc函数:

public int nextDoc() throws IOException {

    if (reqScorer == null) {

       return doc;

    }

    doc = reqScorer.nextDoc();

    if (doc == NO_MORE_DOCS) {

       reqScorer = null; // exhausted, nothing left

       return doc;

    }

    if (exclDisi == null) {

       return doc;

    }

    return doc = toNonExcluded();

}

         就看最后一句toNonExcluded

private int toNonExcluded() throws IOException {

    int exclDoc = exclDisi.docID();

    int reqDoc = reqScorer.docID(); // may be excluded

    do {

       if (reqDoc < exclDoc) {

           return reqDoc; // reqScorer advanced to before exclScorer, ie.

                         // not excluded

       } else if (reqDoc > exclDoc) {

           exclDoc = exclDisi.advance(reqDoc);

           if (exclDoc == NO_MORE_DOCS) {

              exclDisi = null; // exhausted, no more exclusions

              return reqDoc;

           }

           if (exclDoc > reqDoc) {

              return reqDoc; // not excluded

           }

       }

    } while ((reqDoc = reqScorer.nextDoc()) != NO_MORE_DOCS);

    reqScorer = null; // exhausted, nothing left

    return NO_MORE_DOCS;

}

         reqDocMUST得到的第一个文档idexclDoc是要被排除的第一个文档id,看do/while中的第一个if,如果reqDoc小于exclDoc,当然就没有被排除,如果reqDoc>exclDoc,那就不知道是不是要排除,exclDisi前进,若这时exclDoc大于reqDoc,那不排除。这里要注意,只有大于,小于在代码中表现了,那剩下的一种自然就是等于了,也就是被排除,所以,reqScorer要赋以reqDoc下一个文档。

 

 

 

 

 

 

 

 

 

 

 

 

  评论这张
 
阅读(843)| 评论(0)
推荐 转载

历史上的今天

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2017