平常在做專案尤其是處理訂單時候,日期搜尋是一定要具備的..
在 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 />");
}
結果:
這樣就可以處理關於日期的範圍搜尋
當然我是很少用到時跟分,如果有需要也是可以加入索引後搜尋
Source