摘要:Lucene.Net
Lucene.Net 3.03 版本 (在語法上與之前的版本有些微差異) , 筆者使用此版本
(1)在語法上與之前的版本有些微差異
(2)Runtime4.0
Lucene.Net 2.9.2.2
(1)Runtime2.0
開發環境 : Visual Studio 2010
Dll檔 : 可至http://lucenenet.apache.org/ 下載
Lucene.Net 是一套搜尋引擎的 Library , 最早是建立在 Java 的專案上 ,
而 Lucene.Net 是特別建立在 .Net 的 Runtime 上 .
一般 Lucene.Net 常常被拿來跟 SQL Server 的 Full-Text Search 拿來比較
Lucene 與 SQL Server FTS 比較 :
Lucene | SQL Server FTS | |
倒排索引 | Yes | Yes |
支援中 , 英文分詞 | 需使用外部的 Library | Yes |
Index 自動更新 | No | Yes |
能否儲存 Index 在記憶體 | Yes | No |
能否在 Index 儲存資料 | Yes | No |
使用方式 | API | SQL Server |
停用詞,同義詞支援 | Yes | Yes |
萬用字元支援 | Yes | No |
(1) SQL Server 與 Lucene.Net 都採用 Inverted Index ( 倒排索引 ) 的方式建立索引
有關 SQL Server 使用 Inverted Index 的敘述可觀看網址 , 在 Full-text Search Processing 的段落有提到
(2) SQL Server 在佈署上比 Lucene 容易許多 , 而 Lucene 有比較高的學習門檻
例如有一堆 API 需要學習
有興趣的讀者可至下列網址參考兩種做法的差異 :
SQL Server and regular expressions
對於 SQL Server 與 Lucene 的差異在效果與效能的差異可以參考下列連結 :
Comparing Microsoft SQL Server FTS and Apache Lucene
The following will demo :
我們將從一段內容中找到我們所需要的關鍵字 "holmes"
內容 : 但是holmes 是一個專業Programer
Step1 : Build Index :
public void BuildIndex()
{
//從App_Data底下讀入Index檔案 , 若沒有會自動建立
DirectoryInfo dirInfo = new DirectoryInfo(AppDomain.CurrentDomain.BaseDirectory.ToString() + "\\App_Data");
FSDirectory dir = FSDirectory.Open(dirInfo);
IndexWriter iw = new IndexWriter(dir, new StandardAnalyzer(Version.LUCENE_30), true, IndexWriter.MaxFieldLength.UNLIMITED);
//這裡將會寫進一份文件,而文件包含許多field(屬性),你可以決定這些屬性是否需要被索引
Document doc = new Document();
Field field = new Field("ID", "holmes2136", Field.Store.YES, Field.Index.ANALYZED, Field.TermVector.NO);
Field field2 = new Field("DESC", "但是Holmes是專業PG", Field.Store.YES, Field.Index.ANALYZED, Field.TermVector.NO);
doc.Add(field);
doc.Add(field2);
iw.AddDocument(doc);
iw.Optimize();
iw.Commit();
//IndexWriter有實作IDisposable ,
//表示握有外部資源,所以記的得Close
iw.Close();
}
我們可以看到在建立 Field Instance 時 , 需丟入五個參數 , 依序為 :
一. 欄位名稱
二. 欄位 value
三. 是否儲存 是否要儲存資料於索引中 , 較適合儲存小量的資料來源
- Field.Store.Yes
- Field.Store.No
四. 是否索引 該資料來源的資料是否要在使用者搜尋時被檢索
- NO 表示該 Field 不需要索引 , 也就是使用者不需要去尋找該 Field 的值
- ANALYZED 表示該 Field 先分詞在索引
- NOT_ANALYZED 表示不對該 Field 進行分詞 , 但是要對它進行索引 , 也就是該 Field 會被使用者尋找
- NOT_ANALYZED_NO_NORMS 表示對該 Field 進行索引 , 但是不使用 Analyzer , 同時禁止參與評分
- ANALYZED_NO_NORMS 表示對該 Field 進行索引 , 但是使用 Analyzer , 同時禁止參與評分
五. 是否分詞 資料來源的資料是否要經過分詞
Step2 : Search :
public void Search(string keyWord) {
string indexPath = AppDomain.CurrentDomain.BaseDirectory.ToString() + "\\App_Data\\";
DirectoryInfo dirInfo = new DirectoryInfo(indexPath);
FSDirectory dir = FSDirectory.Open(dirInfo);
IndexSearcher search = new IndexSearcher(dir, true);
// 針對 DESC 欄位進行搜尋
QueryParser parser = new QueryParser(Lucene.Net.Util.Version.LUCENE_30, "DESC", new StandardAnalyzer(Lucene.Net.Util.Version.LUCENE_30));
// 搜尋的關鍵字
Query query = parser.Parse(keyWord);
// 開始搜尋
var hits = search.Search(query, null, search.MaxDoc).ScoreDocs;
foreach (var res in hits)
{
Response.Write(string.Format("ID:{0} / DESC{1}",search.Doc(res.Doc).Get("ID").ToString()
,search.Doc(res.Doc).Get("DESC").ToString().Replace(keyWord, "" + keyWord + "") + "
"));
}
}
Step3 : Result
ID:holmes2136 / DESC但是Holmes是專業PG
何謂倒排索引 ( Inverted Index ) :
當我們在閱讀一本書時 , 通常使用頁數來尋找相關內容 , 每一頁上具有一定數量的文字 ,
這些文字記錄了資訊 , 當使用倒排方式後 , 不再有整頁的資訊 , 資訊被切割成一個個的關鍵字 ,
並輔以關鍵字所在原書中的頁數 , 而構成一個倒排基本單位 ---- 開發專屬個人的引擎一書
參考來源 :
開發專屬個人的搜尋引擎書籍