轉載地址:http://blog.csdn.net/xuezhongsong/article/details/4388241
在建立索引前,先了解下lucene中的一些與索引相關的重要類。
為了對文檔進行索引,Lucene 提供了五個基礎的類,他們分別是 Document, Field, IndexWriter, Analyzer, Directory。下面我們分別介紹一下這五個類的用途:
Document
Document 是用來描述文檔的,這里的文檔可以指一個 HTML 頁面,一封電子郵件,或者是一個文本文件。一個 Document 對象由多個 Field 對象組成的。可以把一個 Document 對象想象成數據庫中的一個記錄,而每個 Field 對象就是記錄的一個字段。在建立索引的時候,也就是實例化一個索引器IndexWriter的之前,必須通過已經建立好的Document邏輯文件,將 Document的對象添加到IndexWriter實例中,才能算是建立索引。
Field
Field 對象是用來描述一個文檔的某個屬性的,比如一封電子郵件的標題和內容可以用兩個 Field 對象分別描述。
Document匯集數據源,這個數據源是通過Field來構造的。構造好Field之后,將每個Field對象加入到Document之中,可以通過Document來管理Field,然后將聚集的Document加入到IndexWriter中,建立索引,寫入指定的Directory,為檢索做準備。
Analyzer
在一個文檔被索引之前,首先需要對文檔內容進行分詞處理,這部分工作就是由 Analyzer 來做的。Analyzer 類是一個抽象類,它有多個實現。針對不同的語言和應用需要選擇適合的 Analyzer。Analyzer 把分詞后的內容交給 IndexWriter 來建立索引。
IndexWriter
IndexWriter 是 Lucene 用來創建索引的一個核心的類,他的作用是把一個個的 Document 對象加到索引中來。建立索引必須從它開始。而且,從它的構造函數開始。
Directory
這個類代表了 Lucene 的索引的存儲的位置,這是一個抽象類,它目前有兩個實現,第一個是 FSDirectory,它表示一個存儲在文件系統中的索引的位置。第二個是 RAMDirectory,它表示一個存儲在內存當中的索引的位置
Field函數:public Field(string name, string value_Renamed, Field.Store store, Field.Index index)
??????????????? Field函數 第一個參數是字段名稱,第二個參數是字段內容,第三個參數是存儲類型,第四個參數是索引類型 ??????????????? Field.Store: 有三個屬性: ??????????????? Field.Store.YES:索引文件本來只存儲索引數據, 此設計將原文內容直接也存儲在索引文件中,如文檔的標題。 ??????????????? Field.Store.NO:原文不存儲在索引文件中,搜索結果命中后,再根據其他附加屬性如文件的Path,數據庫的主鍵等,重新連接打開原文,適合原文內容較大的情況。 ??????????????? Field.Store.COMPRESS 壓縮存儲;
??????????????? Field.Index:有四個屬性: ??????????????? Field.Index.TOKENIZED:分詞索引 ??????????????? Field.Index.UN_TOKENIZED:進行索引,但不對其進行分詞,如作者名,日期等,Rod Johnson本身為一單詞,不再需要分詞。 ??????????????? Field.Index.NO 和 Field.Index.NO_NORMS: ??????????????? 不進行索引,存放不能被搜索的內容如文檔的一些附加屬性如文檔類型, URL等。
/** 建立一個Form,命名為DemoIndex,添加四個控件:* Button按鈕命名button1,添加單擊事件* RichTextBox控件,命名richTextBox1* StatusBar,命名statusBar1* FolderBrowserDialog,命名folderBrowserDialog1* 分詞類使用中文分詞類庫ChineseAnalyzer,也可以使用Lucene自帶的類庫*/
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using Lucene.Net.Documents;
using Lucene.Net.Index;
using Lucene.Net.QueryParsers;
using Lucene.Net.Analysis.Cn;
using System.IO;namespace WebCheck
{public partial class DemoIndex : Form{public DemoIndex(){InitializeComponent();}const string INDEX_STORE_PATH = "index";DateTime start = DateTime.Now;private void button1_Click(object sender, EventArgs e){DialogResult result = folderBrowserDialog1.ShowDialog();if (result == DialogResult.OK){IndexWriter writer = null;try{///INDEX_STORE_PATH索引所在目錄,ChineseAnalyzer()分詞類,true是新建索引,flase追加索引。writer = new IndexWriter(INDEX_STORE_PATH, new ChineseAnalyzer(), true);writer.SetMaxFieldLength(250000);//設置建立索引的長度,就是對數據的前多少條建立索引 writer.SetMaxBufferedDocs(100);//控制寫入一個新的segment前內存中保存的document的數目,設置較大的數目可以加快建索引速度 writer.SetMaxMergeDocs(100);// 控制一個segment中可以保存的最大document數目,值較小有利于追加索引的速度 writer.SetMergeFactor(100);// 控制多個segment合并的頻率,值較大時建立索引速度較快,默認是10 output("開始建立索引..../n");start = DateTime.Now;#region 同步索引//IndexDirectory(writer,new FileInfo(this.folderBrowserDialog1.SelectedPath));//如果是同步索引的話,調用優化索引的函數可以對索引優化,如果是異步就不行了。//異步的話,最好把writer也當做參數傳遞給回調函數里,在回調函數里優化,這里//傳遞了一個時間參數進去,你可以傳遞一個包含start和writer的自定義對象進去。//為了讓示例簡單我沒有這個做。//writer.Optimize();//writer.Close();#endregion#region 異步索引// BeginInvoke 方法可啟動異步調用。//它與您需要異步執行的方法具有相同的參數,另外它還有兩個可選參數。//第一個參數是一個 AsyncCallback 委托,該委托引用在異步調用完成時要調用的方法。//第二個參數是一個用戶定義的對象,該對象可向回調方法傳遞信息。//BeginInvoke 立即返回,不等待異步調用完成。BeginInvoke 會返回 IAsyncResult,這個結果可用于監視異步調用進度。//結果對象IAsyncResult是從開始操作返回的,并且可用于獲取有關異步開始操作是否已完成的狀態。//結果對象被傳遞到結束操作,該操作返回調用的最終返回值。//在開始操作中可以提供可選的回調。如果提供回調,在調用結束后,將調用該回調;并且回調中的代碼可以調用結束操作。CheckForIllegalCrossThreadCalls = false;AsyncIndexDirectoryCaller caller = new AsyncIndexDirectoryCaller(IndexDirectory);IAsyncResult ar = caller.BeginInvoke(writer, new FileInfo(this.folderBrowserDialog1.SelectedPath), new AsyncCallback(searchCallback), writer);caller.EndInvoke(ar);this.statusBar1.Text = "準備";#endregion}catch (Exception ex){output(ex.Message);}}}delegate void AsyncIndexDirectoryCaller(IndexWriter writer, FileInfo file);//委托public void IndexDirectory(IndexWriter writer, FileInfo file){if (Directory.Exists(file.FullName))//如果file是一個目錄(該目錄下面可能有文件、目錄文件、空文件三種情況){String[] files = Directory.GetFileSystemEntries(file.FullName);//獲取此目錄下子目錄和文件集合if (files != null){for (int i = 0; i < files.Length; i++){IndexDirectory(writer, new FileInfo(files[i])); //這里是一個遞歸 }}}else // 到達葉節點時,說明是一個File,而不是目錄,則建立索引{if (file.Extension == ".txt" || file.Extension == ".htm" || file.Extension == ".html")//指定為特定的頁面建立索引{IndexFile(file, writer);}}}private void IndexFile(FileInfo file, IndexWriter writer){try{Document doc = new Document();output("正在建立索引" + file.FullName);//Field函數 第一個參數是字段名稱,第二個參數是字段內容,第三個參數是存儲類型,第四個參數是索引類型//Field.Store: 有三個屬性://Field.Store.YES:索引文件本來只存儲索引數據, 此設計將原文內容直接也存儲在索引文件中,如文檔的標題。 //Field.Store.NO:原文不存儲在索引文件中,搜索結果命中后,再根據其他附加屬性如文件的Path,數據庫的主鍵等,重新連接打開原文,適合原文內容較大的情況。 //Field.Store.COMPRESS 壓縮存儲; //Field.Index:有四個屬性://Field.Index.TOKENIZED:分詞索引 //Field.Index.UN_TOKENIZED:不分詞進行索引,如作者名,日期等,Rod Johnson本身為一單詞,不再需要分詞。 //Field.Index.NO 和 Field.Index.NO_NORMS://不進行索引,存放不能被搜索的內容如文檔的一些附加屬性如文檔類型, URL等。 doc.Add(new Field("filename", file.FullName, Field.Store.YES, Field.Index.NO_NORMS));//這里一定要設置響應的編碼格式,否則建立索引的時候不能正確讀取內容并分詞doc.Add(new Field("contents", GetContent(file), Field.Store.NO, Field.Index.UN_TOKENIZED));writer.AddDocument(doc);}catch (FileNotFoundException fnfe){output(fnfe.Message);}}/// <summary>/// /// </summary>/// <param name="file"></param>/// <returns></returns>private string GetContent(FileInfo file){string content = "";StreamReader filestream = new StreamReader(file.FullName, System.Text.Encoding.Default);content = filestream.ReadToEnd();filestream.Close();if (file.Extension == ".htm" || file.Extension == ".html"){content = parseHtml(content);}return content;}/// <summary>/// 出去網頁中的html字符/// </summary>/// <param name="html"></param>/// <returns></returns>private string parseHtml(string html){string temp = System.Text.RegularExpressions.Regex.Replace(html, "<[^>]*>", "");return temp.Replace(" ", " ");}void searchCallback(IAsyncResult ar){IndexWriter writer = (IndexWriter)ar.AsyncState;writer.Optimize();//Optimize()方法是對索引進行優化writer.Close();TimeSpan s = DateTime.Now - start;output("索引完成,共用時" + s.Milliseconds + "毫秒");MessageBox.Show("索引完成,共用時" + s.Milliseconds + "毫秒", "提示");}void output(string s){richTextBox1.AppendText(s + "/n");this.statusBar1.Text = s;}}
}
轉載于:https://www.cnblogs.com/smthts/archive/2012/10/16/2726974.html
總結
以上是生活随笔 為你收集整理的Lucene.Net---1索引的建立 的全部內容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔 網站內容還不錯,歡迎將生活随笔 推薦給好友。