2012-10-05

[C#] Lucene.net–透過 Filter 過濾條件

 

上一篇文章 談到 透過 TermRangeQuery 進行日期搜尋

其實透過查詢的方法不只有 Query 還有 Filter 可以用..

像是原本使用 Query 查詢 日期範圍:

C# Code :

// 其 parameters 為  欄位名稱, 下底 (小值), 上底 (大值), 是否包含最小值, 是否包含最大值
Query query1 = new TermRangeQuery("BirthDay", "19001101", "19001202", true, true);
var hits = search.Search(query1, null, search.MaxDoc()).ScoreDocs;

可以直接使用 Filter 做過濾..


TermRangeFilter 過濾時間



 



// 啟用監看
Stopwatch sw = new Stopwatch();
sw.Start();
// 讀取索引
string indexPath = AppDomain.CurrentDomain.BaseDirectory.ToString() + "\\Index1\\";
DirectoryInfo dirInfo = new DirectoryInfo(indexPath);
FSDirectory dir = FSDirectory.Open(dirInfo);
IndexSearcher search = new IndexSearcher(dir, true);
       
// 查詢條件就是直接所有文件
Query q = new MatchAllDocsQuery();
// 其 parameters 為  欄位名稱, 下底 (小值), 上底 (大值), 是否包含最小值, 是否包含最大值
Filter filter = new TermRangeFilter("BirthDay", "19001101", "19001202", true, true);
var hits = search.Search(q, filter, search.MaxDoc()).ScoreDocs;
sw.Stop();
Response.Write("花費時間:" + sw.Elapsed + "<br /><hr />");
Response.Write("資料比數:" + hits.Length + "<br /><hr />");
Response.Write("Result:<br />");
foreach (var res in hits)
{
    // 顯示
    Response.Write("Id:" + search.Doc(res.doc).Get("Id") + "  BirthDay=" + search.Doc(res.doc).Get("BirthDay") + "  Memo=" + search.Doc(res.doc).Get("Memo").ToString().Replace(txtKeyword.Text, "<span style='color:red'>" + txtKeyword.Text + "</span>") + "<br />");
}

但是網路上我看過一些文獻有寫到,使用 Filter 它的效率會來得比較差…


我現在自己的作法都是,大體條件我都會使用 Query 如果一些特殊條件我才會用 Filter 進行過濾..


譬如: 這個月訂單我會用 Query 搜尋出來,之後再用 Filter 去過濾一些狀態..


這裡是我使用 Query 連續測試的結果 (測試資料十萬筆 連續跑 20 次所記錄下來的時間)


Query                         Filter:


sshot-56_thumbsshot-55_thumb


對 Lucene 來說十萬筆資料太少了,所以可能只有些微的差距,如果有機會我拿到 n 百萬的資料我再來測一下


是感覺到似乎使用 Filter 會慢一點點點.. 不過也才差 0.01~0.02 秒..