Lucene.net 原理介紹以及使用方法


 
         
在我將要實現的仿照博客園搜索功能的簡易網站中,需要用到Lucene.net進行查詢,因此我整理了一下我收集的資料。
 
現實世界中包含兩種類型的數據:結構化數據和非結構化數據
 
結構化數據很容易進行搜索,比如數據庫包含的就是結構化數據,可以利用sql進行查詢。但是對於非結構化數據,比如word、txt文件中包含的內容則屬於非結構化數據。要對這些數據進行查找,只能采用順序掃描的方式,但是順序掃描的方式速度很慢。
 
         
但是在Lucene的世界中,把所有數據都作為字符串來處理,通過Lucene來進行查找,通常會分成兩步,一步就是創建索引,另一步就是查找索引。
 
         
因為創建好的索引屬於結構化數據,所以可以很快的進行查找。並且Lucene創建索引的方式采用的倒排索引的存儲。
 
         
 
 
         
每個字符串都指向包含此字符串的文檔(Document)鏈表,稱謂倒排表。采用倒排表進行存儲的索引結構就稱為倒排索引。
 
 
         
也許有人會說,創建索引的時間會非常長,加上搜索索引的時間不一定會比直接采用順序查找的速度要快。這個看法我是很贊同的,我就曾經采用Lucene創建索引,索引一篇word書籍,整整索引了八個小時才完成。我想如果我打開word直接查找也就是幾分鍾的事情。但是我為什么非要建立索引不可呢?原因也很簡單,就是順序掃描每次搜索都會重新執行一次,但是索引只需要索引一次,以后就都可以使用。這也就是創建索引的根本目的:一次索引,多次使用。
 
         
在搜索的過程中,我們往往是想讓相關度較高的排在前面,這就會用到權重的概念。
 
         
 
         
找出詞(Term)對文檔重要性的過程稱為計算詞的權重(Weight)的過程。搜索出來的文檔應該是按照權重的順序進行排列,按從小到大的次序。
 
         
計算詞的權重會關系到兩個參數,一個是詞(Term),另一個是文檔(Document).
 
         
詞的權重表示的是此詞在此文檔中的重要程度,越重要的詞有越大的權重,因而在計算文檔之間的相關性中將發揮更大的作用。
 
         
 
 
         
Lucene搜索過程通常分為三步:創建、索引、搜索
 
         
  • 被索引的文檔用Document對象表示
  • IndexWriter通過函數adDocument將文檔添加到索引中,實現創建索引的過程
  • Lucene的索引采用的反向索引。對應我前面說的反向鏈表
  • 當用戶有請求時,Query代表用戶的查詢語句。
  • IndexSearcher通過函數search搜索    Lucene Index
  • IndexSearcher計算term weight和score並且將結果返回給用戶。再返回給用戶數據之前,Lucene還會按照權重進行排序
  • 返回給用戶的文檔集合用TopDocsCollector表示

Lucene中的基本概念:Term (詞) Document(文檔) Field(字段(和數據庫字段類似)) Query(查詢) QueryParser(查詢解析器) IndexWriter(負責生成索引並存儲)

IndexReader(讀取硬盤中的索引文件並存入內存) Hits(命中 我也不能很好的翻譯這個詞的意思 就是返回搜索的數據)


Lucene。net的基本使用方法


1 public void CreateIndex()//創建索引 2 { 3 Document doc = new Document(); 4 doc.Add(new Field("name", "我是郭志奇", Field.Store.YES, Field.Index.NOT_ANALYZED)); 5 doc.Add(new Field("val", "", Field.Store.YES, Field.Index.ANALYZED)); 6 IndexWriter writer = new IndexWriter(FSDirectory.Open(new DirectoryInfo("")), new Standard Analyzer(), true, IndexWriter.MaxFieldLength.LIMITED); 7 writer.AddDocument(doc); 8 writer.Optimize(); 9 writer.Close(); 10 } 11 12 13 public void Search(string queryString, int num)//搜索 14 { 15 IndexReader reader = IndexReader.Open("", true); 16 IndexSearcher searcher = new IndexSearcher(reader); 17 //創建查詢 18 Analyzer analyzer = new StandardAnalyzer(Lucene.Net.Util.Version.LUCENE_29); 19 QueryParser parser = new QueryParser("", analyzer); 20 Query query = parser.Parse(queryString); 21 TopScoreDocCollector collector = TopScoreDocCollector.create(num, true); 22 Hits hits = searcher.Search(query); 23 //以后就可以對獲取到的collector數據進行操作 24 for (int i = 0; i < hits.Length(); i++) 25 { 26 Document doc = hits.Doc(i); 27 Field keyFieldVal = doc.GetField("key"); 28 string strKey = keyFieldVal.StringValue();//獲取到Field 鍵值key的值 29 } 30 } 31 public void DeleteIndex()//刪除索引 32 { 33 34 IndexWriter writer = new IndexWriter(FSDirectory.Open(new DirectoryInfo("")), new Standard Analyzer(), true, IndexWriter.MaxFieldLength.LIMITED); 35 writer.DeleteAll();//刪除所有的索引 36 writer.DeleteDocuments(new Term("key", "val"));//刪除該詞條 37 //注意 在執行這個刪除操作的時候,其實lucene本身並沒有將數據從硬盤刪除,而是保存到了一個單獨的后綴名為.del的文件中。 38 writer.Commit();//進行提交操作 標記為刪除的索引會被從硬盤刪除 39 40 }


Lucene可以進行的操作方法有很多,分詞器也有很多,但是Lucene.net自帶的分詞器不能很好的支持中文,因此對於有中文的搜索我推薦盤古分詞,很好很強大。
還有一點用慣.net的朋友使用Lucene.net的時候會覺得不習慣,因為在.net中是屬性的東西,在Lucene.net中是用方法表示的,因為據我所知,在Java中是不存在和.net中的屬性一說的。

索引:
Asp.net MVC 使用Autofac的簡單使用 IOC (2012-12-12 13:16)   8 649 547    
Asp.net MVC 仿照博客園的簡單網站首頁 列表設計 (2012-12-11 22:21) 發布 12 928 277    
為什么要從Web form過渡到MVC中 (2012-12-09 22:43) 發布 88 5253 478    
Asp.net MVC3 企業網站系統高仿博客園 首頁左側列表頁面 實現效果 (2012-12-08 19:11) 發布 41 2506 361    
Asp.net MVC 3 開發企業網站系統仿照博客園部分功能--總體設計 (2012-12-05 23:41) 發布 36 2064 515    
Asp.net MVC 3 開發簡單的企業系統開篇--數據庫 (2012-12-03 21:03) 發布 43 3016 351    
Asp.net MVC 3 開發一個簡單的企業網站系統 (2012-12-02 21:09)
 
        

 


免責聲明!

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



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