booleanquery對兩種不同查詢場景執行不同的演算法:
場景1:
所有的子句都必須滿足,而且所有的子句裡沒有巢狀booleanquery。
例:
a and b and c
上面語句表示要同時包含a,b,c三個字元(詞元)的文件,假如現在索引裡包含a的文件有4,6,8;b的文件有:2,4,6;c的文件有:3,4,5,這個語句就是找出編號為4的這個文件。
注:在倒排索引裡儲存的包含某個詞元的文件列表都是從小到大排列的。
初始狀態如下:ab
c-> 4
-> 2
-> 364
4865
指標表示當前遍歷到哪個文件
第一步:按照每個詞元文件列表的第乙個文件對詞元排序。排序以後的狀態如下:bc
a-> 2
-> 3
-> 444
6658
第二步:判斷第乙個詞元(b)的當前遍歷文件(2)是否小於最後乙個詞元(a)的當前遍歷文件(4)。如果小於,則表示第乙個詞元的當前遍歷文件不是符合的文件,如果是符合的最後乙個詞元的當前文件應該和第乙個詞元的相同。
第三步: 第乙個詞元文件位置(2)跳轉到最後乙個詞元的當前遍歷的文件(4),跳轉以後的狀態如下:bc
a2-> 3
-> 4
-> 446
658第四步: 將第乙個詞元放到詞元列表最後,重置位置後狀態如下:ca
b-> 3
-> 424
6-> 458
6重複第
二、三、四步,直到找到第乙個詞元的當前遍歷文件id和最後乙個詞元的相同,則這個文件就是符合查詢要求的文件。
這種場景的**實現在conjunctionscorer類裡,主要的**邏輯在方法donext裡:
while (more && first().doc() < last().doc())
這裡會不斷的判斷第乙個詞元的當前文件是否小於最後乙個詞元的當前文件,如果不相同,則第乙個詞元的文件跳轉到最後乙個詞元的文件位置。
排序是在第一次進去的時候在init方法裡做的。
場景2:
除了上面第一種場景就是第二種場景,第一種場景因為排序的原因,不需要遍歷所有的文件,第二種場景需要遍歷所有的文件。
第二種場景的實現在booleanscorer類裡,
每次往booleanscorer類裡新增乙個子句,會記錄當前這個子句的序號和這個子句的定義,是必須滿足還是必須不滿足。這個資料記錄在requiredmask和prohibitedmask中,這兩個數是int型別,裡面每一位都代表乙個子句。requiredmask記錄了哪些子句必須滿足;prohibitedmask記錄了哪些子句必須不能滿足。比如一共有5個子句,1、3、5必須滿足,2、4必須不能滿足,則requiredmask二進位制的值為: 10101。prohibitedmask的值為: 01010。
當呼叫next的時候會批量從各子句中取出符合這些子句的部分文件(文件id批範圍,1024為一批)到記憶體中的乙個快取buckettabke裡,在這個快取裡會根據文件id進行聚合(bucket),每個文件id都有個滿足哪些子句的屬性bits。
然後遍歷這些文件,那些bits裡包含所有必須符合子句且不包含所有必須排查子句的文件是最終符合的文件。這個判斷是通過bits和上面requiredmask和prohibitedmask做位運算實現的。
if ((current.bits & prohibitedmask) == 0 &&(current.bits & requiredmask) ==requiredmask)
lucene booleanquery組合查詢
當parse函式中指定多個項時,queryparser能很方便地構建booleanquery物件。使用圓括號分組,通過指定的 and or以及not這些操作符。允許進行邏輯的and or或not組合,通過booleanquery的add方法將乙個查詢子句增加到某個booleanquery物件中 pu...
lucene booleanquery組合查詢
當parse函式中指定多個項時,queryparser能很方便地構建booleanquery物件。使用圓括號分組,通過指定的 and or以及not這些操作符。允許進行邏輯的and or或not組合,通過booleanquery的add方法將乙個查詢子句增加到某個booleanquery物件中 pu...
KNN,TC text category 基本演算法
knn分類演算法 knn分類演算法是一種傳統的基於統計的模式識別方法。演算法思想很簡單 對於一篇待分類文件,系統在訓練集中找到k個最相近的鄰居,使用這k個鄰居的類別為該文件的候選類別。該文件與k個鄰居之間的相似度按類別分別求和,減去乙個預先得到的截尾閾值,就得到該文件的類別測度。用knn也表示所選k...