背景
網上的文章各式各樣,還不如看看源碼
參考
他的一本“書“ 寫的比較明白,可供參考:
看上面這個博客基本可以看懂原理。建議大家先讀一讀,配圖也比較豐富,比較好理解。
但是這個博客已經比較老了,不禁讓人懷疑新的版本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