多个term查询的步骤

多个term查询的步骤
分别查找每个term对应的结果
查询步骤
Term :a  -----》tii-------》tis-------》frg  保存结果 --- TermScorer1

Term :b  -----》tii-------》tis-------》frg  保存结果---  TermScorer2



得到结果集分别缓存在TermScorer二个数组里面

doc[]
frg[]
这个二个数组的大小为32,所以如果查询结果一次最多只取32个

封装查询结果
查询的结果封装为BooleanScorer2,构建BooleanScorer2的时候会创建ConjunctionScorer对象,ConjunctionScorer会在构造函数里面调用doNext()取得第一个查询结果的交集
结果的合并算法
private int doNext() throws IOException {
    int first = 0;
    int doc = scorers[scorers.length - 1].docID();
    Scorer firstScorer;
    while ((firstScorer = scorers[first]).docID() < doc) {
      doc = firstScorer.advance(doc);
      first = first == scorers.length - 1 ? 0 : first + 1;
    }
    return doc;
  }

算法是取最后个结果集的最小的一个docid,在结果集合scorers数组里面每个scorer有个doc属性,保存了一个term结果集里面最小的docId。
Scorers 的保存的对象是有序的,排序的规则是按scorer的doc比较的
算法如下
Arrays.sort(scorers, new Comparator<Scorer>() {         // sort the array
      public int compare(Scorer o1, Scorer o2) {
        return o1.docID() - o2.docID();
      }
});
合并算法的思想是取出最后一个scorer的doc属性的值A,和剩下的scorer的属性doc属性比较,如果小于A,则调用方法doc = firstScorer.advance(doc)取出大于或者等于A的docId。如果没有找到返回NO_MORE_DOCS,这个值其实是Integer.MAX_VALUE。返回这个值表示没有符合条件的docId,则返回,说明没有交集。

举例如下
Scorers[]数组如下


Termscore1   doc =1
              docs []={1,3,5,6,7,8}

Termscore2   doc =2
              docs []={2,4,5,6,7,8}



Termscore3   doc =3
              docs []={3,5,7,8}


Termscore4   doc =5
              docs []={5,6,7,8}


取出Termscore4.doc复制给变量doc

和Scorers[]数组中的scorer对象比较
第一次是和Termscore1.doc比较,小于5
循环Termscore1.docs[] 找出大于等于5的docId是Termscore1.docs[2]
赋值给doc= Termscore1.docs[2];
计算下一个比较对象
first = first == scorers.length - 1 ? 0 : first + 1;

得到first的值是1。取出Scorers[1].doc 和5比较,小于5,循环Scorers[1].docs[] 找出大于等于5的docId是Scorers[1].docs[2],
赋值给doc= Termscore1.docs[2];
计算下一个比较对象
first = first == scorers.length - 1 ? 0 : first + 1;
以此类推,知道比较最后一个对象Scorers[4].doc,发现不小于,说明在所有是数据集之中5是共同的元素。返回5,放到collector里面去。

Collector的收集方法
结果会放在org.apache.lucene.util.PriorityQueue优先队列的一种实现类里面
方法如下,
public final T add(T element) {
    size++;
    heap[size] = element;
    upHeap();
    return heap[1];
  }
Faq
是否会查询所有的结果进行合并?
是的,lucene, scorers[length-1] 中docs [] 32 个docId用完了,会再去读文件,其余的scorer 会去读文件用DefaultSkipListReader读取

你可能感兴趣的:(apache,算法,Lucene)