2012-10-05

[C#] 如何從大量JSON檔案中找尋關鍵字(JSON.net 還原篇)

 

接下來要發一些有關於'搜尋' 資料的文章..

最近遇到一個需求,就是我必須要在一大堆資料 (檔案) 中找尋到某一個關鍵字

偏偏那不是純文字檔,而是 JSON 的格式…

這時候就挑起我的好奇心,到底怎樣可以快速找尋到我要的資料..

首先,要先解決我的問題如何找到資料…

介紹範例資料

首先我在 Source 這檔案夾下面建立 10 萬筆資料,不多,但是也不太少,但是產生跟複製的時候足以讓我電腦 hang 住..

這資料結構長這樣

 
{
"Id":"4",
"Memo":"的,你快挖了丁老賊的眼珠出來,給我報仇。」蕭峰一時難以明白其間真相,目光環掃,在人君中見到了段正淳和",
"Birthday":"1900-01-05T00:00:00",
"Age":4
}




上述為了顯示好看在資料中是無分行的 JSON 資料 命名從 1~100000 所以 Id 跟檔名相同,Age 也是,至於 Memo 資料


1~50000 是從金庸小說天龍八部隨機取出 50 字,50000~100000 是從金庸小說射鵰英雄傳裡面隨機取出 50 字,做成測試資料..


所以您可以透過 段譽、蕭峰等關鍵字搜尋 您可以搜尋出 1~50000 的資料,如果是搜尋 郭靖、黃蓉、洪七公 你會搜尋到 50001~100000 的資料


我在 1,1199,49999,99999 的 Memo 欄位中都加上了當麻的字樣,方便我進行測試…


ps. 下載範例時候,可以下載到這 100000 個檔案,解壓縮的時候可能會花一點時間。



進行搜尋


接下來我們就是把"他們"  讀取出來進行搜尋…


C# Code :



// 使用 Stopwatch 進行監看花費時間
 Stopwatch sw = new Stopwatch();
// 監看開始
 sw.Start();
var sourceDirectoryInfo = new DirectoryInfo(AppDomain.CurrentDomain.BaseDirectory + "\\Source\\");
// 因為未知物件型態所以使用 dynamic 
//File.ReadAllText(x.FullName) 取出檔案夾下面所有檔案 並且讀取內容
 //JsonConvert.DeserializeObject<dynamic>(File.ReadAllText(x.FullName))) 將其 unboxing .
//JsonConvert.DeserializeObject<dynamic>(File.ReadAllText(x.FullName))).Where(x => x.Memo.ToString().Contains(txtKeyword.Text)) 搜尋出所帶有的關鍵字
 dynamic allObjects =
    sourceDirectoryInfo.GetFiles().Select(
        x => JsonConvert.DeserializeObject<dynamic>(File.ReadAllText(x.FullName))).Where(x => x.Memo.ToString().Contains(txtKeyword.Text)).ToArray();
// 監看結束
 sw.Stop();
Response.Write("花費時間:" + sw.Elapsed + " <br /><hr />");
Response.Write("資料筆數:" + allObjects.Length + "<br /><hr />");
Response.Write("Result:<br />");
foreach (dynamic obj in allObjects)
{
    Response.Write("Id:" + obj.Id + "  Memo=" + obj.Memo.ToString().Replace(txtKeyword.Text, "<span style='color:red'>" + txtKeyword.Text + "</span>") + "<br />");
}

看一下結果:



搜尋 關鍵字: 當麻


sshot-12_4


連續測試五次分別時間為:


第一次:花費時間:00:00:50.4927420
第二次:花費時間:00:00:26.2773594
第三次:花費時間:00:00:26.2117427
第四次:花費時間:00:00:27.0565036
第五次:花費時間:00:00:26.7758970



搜尋 關鍵字: 黃蓉


sshot-13_2


花費時間:00:00:27.6738803



搜尋 關鍵字: 段譽


 


sshot-14_2


花費時間:00:00:27.2426821



結論


目標資料十萬筆,讀取檔案後,使用 JSON.net 還原其物件,再用.net framework 內建的 Contains 去判斷是否有此關鍵字,


無論資料大小目前大約都在 26~27 秒可以完成,暫時算達到搜尋任務….


範例下載