Lucene.net常用功能說明


 

Lucene.net是一個.net下的全文檢索類庫。配置簡單,功能豐富,比較成熟。我在項目中用Lucene.net有一段時間了,這里我把常用一些功能寫出來,與大家一起分享。

Lucene.net用的是3.0版本,分詞采用盤古分詞。示例程序用VS2010進行編譯。

1         索引

在做索引時,有些參數是需要配置的,下面介紹下常用的參數配置。

1)      數據類型,如整形、時間、字符。

每種類型生成的索引方式都是不同的。比如:字符串需要分詞,整形數據則不需要。生成索引的方式會影響到檢索,如果整形按照字符串的方式生成索引,則比較不容易實現區域檢索:如,ID>1000 and ID<2000。

時間索引比較特殊一些。Lucene.net無法對時間字段進行排序和區域檢索,所以,要把時間字段轉成長整形來實現。時間索引參考如下代碼:

var time = DateTime.Now;

var timeField = new NumericField("Publish", Field.Store.YES, true).SetLongValue(time.Ticks);

2)      是否存儲元數據。

如果進行存儲,Lucene則會把索引數據與元數據同時進行存儲。

好處:取數據比較容易。

壞處:索引比較大,可能會影響檢索的速度

3)      是否進行排序

Lucene.net是支持排序的,包括整形排序、時間排序、字符串排序。

但排序和索引有什么關系呢?

我們知道Lucene.net做索引時,需要把字符串數據進行分詞,便於實現全文檢索。這時,如果一段文字已經分過詞,如:“我的未來不是夢”,分詞后應該是:我-的-未來-不是-夢,這樣,一段文字分成若干個詞進行索引,索引時,詞的順序也發生了變化。其中有一些詞或符號在索引時會被濾掉,所以就無法進行排序了。如果要排序,則不應該進行分詞。做索引時參考如下代碼:

var filed = new Field("title_sort", "我的未來不是夢", Field.Store.NO, Field.Index.NOT_ANALYZED);

如果一個字段,既要實現模糊檢索,又要實現精確匹配或排序,則應該把這個字段做兩份索引,一份分詞,一份不分詞。

2         檢索

1)      字符串檢索

字符檢索時,一般要對關鍵詞進行分詞。

var keywords = ParserKeyWord(keyword);

QueryParser parser = new QueryParser(Lucene.Net.Util.Version.LUCENE_30, item.Column, analyzer);

query = parser.Parse(keywords);

2)      時間、整形檢索

時間和整形都是通過NumericRangeQuery來實現。

NumericRangeQuery<long> query = NumericRangeQuery.NewLongRange("ID", 0, 10000000, true, true);

3)      全詞匹配

如果要實現全詞匹配,在做索引時,該字段就不能進行分詞。

Term t = new Term(item.Column, item.Value.ToString());

query = new TermQuery(t);

4)      多條件檢索

多條件進行檢索可以通過BooleanQuery進行實現,參考如下代碼:

bq.Add(query, Occur.MUST);

bq.Add(query1, Occur.MUST);

這里query可以是任意檢索條件,BooleanQuery只是把條件進行拼接。在多條件的情況下,我們經常會遇到這樣的檢索條件:title =’a’ and (author=’x’ or author =’y’)

遇到這樣的條件時,我們可以使用BooleanQuery進行嵌套。這里我們可以用兩個BooleanQuery實現。

BooleanQuery1用來連接author=’x’和 author =’y’,邏輯運算符為OR

BooleanQuery2用來連接title =’a’和BooleanQuery1,邏輯運算會為And。

5)      多索引檢索

多索引檢索是指同時對多個索引目錄進行檢索。通過MultiSearcher來實現。參考如下代碼:

MultiSearcher multiSearch = new MultiSearcher(allIndexSearch.ToArray());

MultiSearcher初始化時,需要指定多個索引目錄,其它操作與單個索引檢索基本相同。

6)      多索引並行檢索

多索引並行檢索是指同時對多個索引進行並行檢索。當單個索引超過10G大小時,我們可以考慮做多個索引,然后利用並行檢索提高檢索性能。並行檢索通過ParallelMultiSearcher來實現,參考如下代碼:

ParallelMultiSearcher parallelMultiSearch = new ParallelMultiSearcher(allIndexSearch.ToArray());

ParallelMultiSearcher在初始化時,需要指定多個索引目錄,其它操作與單個索引檢索基本相同。

3         排序

Lucene.net支持常見字段的排序。默認按照相關度進行排序。在實現排序之前,一定要做好索引。當對特定字段進行排序時,會嚴重影響檢索的性能,尤其是按字符串進行排序。當數據量比較大時,一定要先做好壓力測試,以便確認lucene.net是否滿足性能要求。

排序是在檢索時,通過SortField來實現的。參考如下代碼:

searcher.Search(query, null, limitCount, new Sort(new SortField("Title", SortField.STRING, true)));

注意SortField.STRING這個參數。這里是字符串,所以用SortField.STRING,如果是整形字段,則參數應該是:SortField.INT。

4         常見問題

1)      時間字段:如果要實現時間字段的排序或區域檢索,一定要把時間字段的值轉成長整形。細節請參考《索引》。

2)      分頁:Lucene.net在檢索時有一個參數:(int n),這個參數是用來取前n條記錄,一般情況下,這個參數n最好不要太大,否則會影響檢索性能。百度即使檢索到1億條記錄,但最多也就顯示760條記錄。我一般都是取1000條記錄,然后在內存中進行分頁。

3)      關於Lucene.net的性能,可以參考:

http://www.cnblogs.com/xingzhang/p/LuceneProject.html

4)      檢索不准:一般情況下檢索不准都與分詞有關。不同的分詞效果會導致檢索與預期的不一致。

5         總結

用Lucene.net有一段時間了,總體感覺很穩定、性能也不錯、功能實現靈活。但Lucene.net畢竟是一個全文索引項目,所以,要完全實現關系型數據庫的功能,如:增、刪、改、查、聯合檢索、分組等,並不容易,而且沒有必要。不要用Lucene.net去代替關系型數據庫,應該把Lucene.net作為關系型數據庫的一個補充。

上面的例子只給出了關鍵代碼或邏輯代碼,下面提供完整的源代碼。

代碼下載

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM