背景
网上的文章各式各样,还不如看看源码
参考
他的一本“书“ 写的比较明白,可供参考:
看上面这个博客基本可以看懂原理。建议大家先读一读,配图也比较丰富,比较好理解。
但是这个博客已经比较老了,不禁让人怀疑新的版本Lucene还是不是这么搞的
那就撸源码吧
看的代码是2020-06-11直接从github 搞下来的。
也可以参考官方文档
按照书上的说法,直接找到Conjunctionxxx 相关的代码。
发现了一个新的神奇类:
org.apache.lucene.search.ConjunctionDISI
DISI 意思是DocIdSetIterator 文档id迭代器
核心代码在这儿:跟书里说的意思是差不多的。
核心函数:iter.advance(doc) : 在iter这个posting_list中,找到第一个大于等于doc的docId。(这里面会用到跳表加速查询)
核心算法:
先找出两个posting_list (lead1和lead2)让他俩找到公共节点,找不到就一直循环到找到位置
当找到了公共节点,再在别的节点中找(others);如果找到一个比当前doc大的(图中215行),说明当前doc不是所有posting_list的公共节点(不是交集),回到lead1跳回去重新找下一个。
这部分建议自己画几个posting_list跟着代码走一遍,神清气爽,秒啊
比如
| lead1 | lead2 | other1 | other2 |
|---|---|---|---|
| 1 | 2 | 4 | 3 |
| 5 | 4 | 5 | 5 |
| ^ | 5 | ^ | ^ |
这样 取出来的交集应该是5