天天看點

Lucene.Net 2.3.1開發介紹 —— 四、搜尋(一)

既然是内容篩選,或者說是搜尋引擎,有索引,必然要有搜尋。搜尋雖然與索引有關,那也隻是與索引後的檔案有關,和索引的程式是無關的,是以,搜尋和索引一般是分開部署。簡單地說,就是一個應用程式(桌面程式)來索引,一個WEB程式來實作搜尋。當然,為了測試的時候簡單,這裡還是使用NUnit的方式運作。搜尋講完後,将會簡單介紹單機搜尋引擎如何部署。

4.1 搜尋與什麼有關

搜尋與什麼有關呢?即使沒有看過前面的文章,那麼現在來随便猜一猜。

首先,搜尋一定與索引有關,如果無關的話,我們根本不需要建立索引。然後,搜尋肯定與分詞有關,因為,索引是在分詞的基礎上建立起來的。還有,分詞一定與查詢關鍵字有關,否則,怎麼去搜尋呢?搜尋确實與上面我們猜到的都有關系,但是,在搜尋裡,分詞的作用和索引中的分詞的作用是不一樣的。

如代碼4.1.1,構造搜尋器用到了上面的三個要素,但是分詞器并沒有和IndexSearcher産生關系。從上面的代碼中也可以看出與搜尋緊密相關的一個是索引檔案,一個查詢表達式。索引檔案就像是資料庫,而查詢表達式就是T-SQL語句。當然,這裡的查詢表達式需要借用分詞器來分詞字元串進而獲得。

4.1.1 搜尋與索引

搜尋和索引是什麼關系?索引是記錄資料的操作,而搜尋是篩選資料的操作,這個本質上和"select * from table"沒有任何差別,但是這裡,這樣使用将使得查詢的速度更加高效。可以說索引在為搜尋作準備,或者說索引是搜尋的資料源。索引的過程是按照一定的結構把各種分散的資料全都集中到這裡來。更準确地說索引這個動作是在為搜尋做準備,而索引檔案本身則隻是資料。

4.1.2 搜尋與表達式

搜尋與表達式是什麼關系呢?想想一下,在資料庫操作中,那麼就是搜尋是一個動作,而表達式呢就是一個表達式,用來篩選的條件表達式。它們是不可分割的一個整體。如果沒有表達式,搜尋就沒有意義;如果不進行搜尋,表達式就是僞代碼,什麼也幹不了。

4.1.3 分詞器與表達式

分詞器則是充當了翻譯的角色,它是索引檔案與查詢表達式溝通的橋梁。如果搜尋和索引使用不同的分詞器,注意,這裡要的是分詞效果不一樣的分詞器,那就搜尋不到想要的東西。表達式解析器将會通過分詞器把一個字元串翻譯成搜尋懂得語言,然後再到索引檔案中進行篩選。

4.1.4 Lucene.Net的搜尋流程

在Lucene.Net中,,把構造表達式考慮進去,那麼搜尋将會要經曆:

(1)、構造查詢表達式;

(2)、打開索引檔案,IndexSearcher會通過IndexReader類打開索引檔案;

(3)、得到查詢表達式的一個篩選值——Weight;

(4)、查詢緩沖中是否有适合的記錄,如果有則讀取,否則擴容,擴容的過程是根據Weight計算出來的;

(4)、傳回結果。

當然,以上的流程是抛開很多分支處理的。

4.2 搜尋核心類

在操作中搜尋将會有到4個核心類。

4.2.1 IndexSearcher

毫無疑問,IndexSearcher肯定是其中的一個。它會打開索引檔案,當然,它不會使用Lucene.Net的鎖,是以,可以了解為隻讀操作。Search方法可以說是它最重要的方法,将由這個方法來傳回我們需要的結果。

4.2.2 Query

Query類作為查詢表達式的載體同樣至關重要。而它的非常多的子類在讓我們頭疼的同時也慶幸有這麼多,才有那麼強大的功能。

4.2.3 QueryParser

QueryParser是Query的構造器,後面将會展示QueryParser和Query一起給我們帶來的神奇體驗。

4.2.4 Hits

從語義上命中的集合,當然就是我們要的結果集。它記錄了我們查詢到的文檔指針,以及這些文檔的幾個重要屬性,比如評分,比如内部ID号。

在講用各個類配合實作查詢之前,将會先浏覽一下Query的各個子類的用途,從下一篇開始。