在上一篇文章索引文件的读取(十)之tim&&tip中我们遗留了一个问题:

  为什么要根据是否达到阈值使用不同的处理方式:

  这个问题可以分解为两个小问题:

  • 问题一:为什么达到阈值后不使用BooleanQuery的方式做文档号的收集
  • 问题二:为什么未达到阈值使用BooleanQuery的方式做文档号的收集

处理方式

  这两种处理方式的不同之处就在于如何根据每个term对应的文档号集合,并从这些集合中获取满足查询条件的文档号集合。

未达到阈值

  未达到阈值的情况下,会根据每个term从索引文件.doc中获取包含这个term的文档号集合,并且用一个long类型的数组docBuffer[ ]来存储文档号集合。注意的是,数组docBuffer[ ]实际上只会存储一个block(见文章索引文件之doc)中的文档号集合,当这个block中的文档号信息读取结束后,会载入下一个block的文档号信息,并写入到数组docBuffer[ ]中,这里为了便于描述,我们假设数组docBuffer[ ]中存储了所有的文档号

  接着使用一个优先级队列DisiPriorityQueue来存储每个term对应的正在被读取的文档号,该队列的排序规则为比较文档号的大小,在执行了排序后,堆顶元素的文档号是最小的,通过排序,更新term对应正在被读取的文档号,直到所有term对应的正在被读取的文档号为Integer.MAX_VALUE,最终文档号按照从小到大的顺序都被取出,我们这里通过一个例子简单介绍下该原理。

图1:

Lucene 索引文件的读取(十一)之tim&&tip

  根据图1中74行的查询条件肉眼可知,域值bcd、ga、gc、gch满足查询条件,这几个term对应的文档号集合,如下所示:

图2:

Lucene 索引文件的读取(十一)之tim&&tip

  获取过程:

图3:

Lucene 索引文件的读取(十一)之tim&&tip

  在最开始,四个docBuffer[ ]数组的第一个数组元素作为每个term正在被读取的文档号存储到优先级队列中,调整堆后如上所示,此时堆顶元素1为满足查询的文档号,它是域值"gc"对应docBuffer[ ]的第一个元素(这里由于域值"bcd"对应的文档号数量多,在源码中用cost来描述,当元素相同时,cost越小,排序位置就越靠前,故尽管它对应的docBuff[ ]的第一个元素也是1,但是堆顶元素选择了域值"gc"对应docBuffer[ ]的第一个元素),随后域值"gc"对应的正在被读取的文档号更新为dcoBuff[ ]数组的下一个数组元素,即文档号3,替换当前的堆顶元素,如下所示:

 

看这里:https://www.amazingkoala.com.cn/Lucene/Search/2020/0819/162.html

相关文章:

  • 2021-04-16
  • 2021-05-19
  • 2021-12-19
  • 2021-06-02
  • 2021-11-26
  • 2021-10-20
  • 2022-12-23
  • 2022-12-23
猜你喜欢
  • 2021-12-23
  • 2021-07-27
  • 2021-12-15
  • 2021-08-24
  • 2021-12-31
  • 2021-10-10
  • 2021-06-06
相关资源
相似解决方案