Lucene.NET 是 Java Lucene 的 C# 移植版,核心流程:
Install-Package Lucene.Net
// 相容 .NET Framework 4.x / .NET Standard 2.0
// 設定路徑
string dataDir = Server.MapPath("~/App_Data/Docs"); // 原始 .txt/.xml 檔案
string indexDir = Server.MapPath("~/App_Data/LuceneIndex"); // 索引目錄
// 1. 確保目錄存在
if (!Directory.Exists(indexDir)) Directory.CreateDirectory(indexDir);
// 2. 分析器 (中文建議 PanGu 或 JiebaNet,此處用 StandardAnalyzer 演示)
var analyzer = new Lucene.Net.Analysis.Standard.StandardAnalyzer(LuceneVersion.LUCENE_48);
// 3. 開啟索引寫入器
using (var dir = FSDirectory.Open(indexDir))
using (var writer = new IndexWriter(dir, new IndexWriterConfig(LuceneVersion.LUCENE_48, analyzer)))
{
var files = new DirectoryInfo(dataDir).GetFiles("*.txt"); // 簡單篩選
foreach (var file in files)
{
string content = File.ReadAllText(file.FullName, Encoding.Default); // 依實際編碼
var doc = new Document();
doc.Add(new TextField("FileName", file.Name, Field.Store.YES));
doc.Add(new TextField("Content", content, Field.Store.YES));
doc.Add(new StringField("Path", file.FullName, Field.Store.YES)); // 不分詞
writer.AddDocument(doc);
}
writer.Commit(); // 或 writer.Flush(triggerMerge: true, applyAllDeletes: true);
}
string keyword = txtKeyword.Text.Trim();
if (string.IsNullOrEmpty(keyword)) return;
using (var dir = FSDirectory.Open(indexDir))
using (var reader = DirectoryReader.Open(dir))
{
var searcher = new IndexSearcher(reader);
// 多欄位查詢解析器
var parser = new MultiFieldQueryParser(LuceneVersion.LUCENE_48,
new[] { "FileName", "Content" }, analyzer);
var query = parser.Parse(keyword);
// 收集前 10 筆最高分
var collector = TopScoreDocCollector.Create(10, true);
searcher.Search(query, collector);
var hits = collector.TopDocs.ScoreDocs;
var sb = new StringBuilder();
sb.Append("<table><tr><th>檔名</th><th>片段</th></tr>");
foreach (var hit in hits)
{
var doc = searcher.Doc(hit.Doc);
string name = doc.Get("FileName");
string content = doc.Get("Content");
string snippet = content.Length > 200 ? content.Substring(0, 200) + "..." : content;
sb.Append($"<tr><td>{name}</td><td>{snippet}</td></tr>");
}
sb.Append("</table>");
litResults.Text = sb.ToString();
}
| Java Lucene | Lucene.NET | 說明 |
|---|---|---|
IndexWriter | IndexWriter | 建立/更新索引 |
IndexReader | DirectoryReader | 唯讀索引讀取 |
IndexSearcher | IndexSearcher | 執行搜尋 |
QueryParser | QueryParser / MultiFieldQueryParser | 字串解析為 Query |
Analyzer | Analyzer | 斷詞/過濾 (Standard, PanGu, Jieba) |
Document | Document | 索引單位 (含多 Field) |
Field | Field / TextField / StringField | 欄位類型 (分詞/不分詞/儲存) |
analyzer 為對應實作即可,索引與查詢**必須使用同一 Analyzer**。writer.ForceMerge(1) 合併段檔 (離線/低峰執行)。QueryCache、FilterCache 重複查詢加速。StringField (不分詞、精確匹配) 用於 ID、路徑、標籤;TextField 用於全文內容。Lucene.NET 提供工業級全文搜尋能力,**核心在於「分析器選擇」與「索引維護策略」**。掌握 IndexWriter 建立索引、MultiFieldQueryParser 多欄位查詢、TopScoreDocCollector 分頁排序三大招式,即可在 ASP.NET 專案快速落地搜尋功能。