2012-10-05

[C#] Lucene.net–透過 TermRangeQuery 進行日期搜尋

 

平常在做專案尤其是處理訂單時候,日期搜尋是一定要具備的..

在 Lucene.net 下面如何進行日期搜尋..

目標資料簡述

每一筆資料大概結構為

{
"Id":"1200",
"Memo":"都是暗自忌憚,同時退開數尺,跟著各自反手,又抓了一名弟子,向前擲出。那兩名弟子又是在半空中一撞,發出",
"Birthday":"1903-04-16T00:00:00",
"Age":1200
}

編號 1~ 1200 其中 Birthday 欄位為 1900/1/2 ~ 1903/4/6



製作索引


製作索引方法請參見 如何從大量 JSON 檔案中找尋關鍵字 (Lucene.net 篇 - 建立索引) ,其中比較值得注意的..


就是建立 Birthday 索引時,其實我放進去的格式為  yyyyMMdd



Field f_BirthDay = new Field("BirthDay", DateTime.Parse(ds["Birthday"].ToString()).ToString("yyyyMMdd"), Field.Store.YES, Field.Index.ANALYZED, Field.TermVector.NO);

 


搜尋指定日期 1900/11/01 ~ 1900/12/02


這時候建立 Query 的時候並非使用 QueryParser.Query 而是使用 TermRangeQuery



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


C# Code :



// 啟用監看
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);
 // 針對 Memo 欄位進行搜尋
    
 // 其 parameters 為  欄位名稱, 下底 (小值), 上底 (大值), 是否包含最小值, 是否包含最大值
 Query query1 = new TermRangeQuery("BirthDay", "19001101", "19001202", true, true);
 
 var hits = search.Search(query1, null, 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 />");
 }

結果:


sshot-53_thumb


這樣就可以處理關於日期的範圍搜尋


當然我是很少用到時跟分,如果有需要也是可以加入索引後搜尋


Source