天天看點

自定義 Azure Table storage 查詢過濾條件

讓我們回到前文中提到的一個問題,如何過濾出 MyLogTable 表中某一天産生的所有日志?在進入細節之前,我們先來回顧一下 MyLogTable 類的設計:

其中,PartitionKey 用來存放産生日志的年份和月份(例如201607表示2016年7月),RowKey 用來存放産生日志的天和時分秒毫秒(例如160934248492表示16号9點34分…)。

在我們設計的 MyLogTable 中,天資訊儲存在 RowKey 的前兩位。我們要做的就是過濾 RowKey 的前兩位,也就是找到所有 RowKey 以”xx”開頭的記錄。這在字元串操作中稱為 StartsWith。遺憾的是現有 Table storage 的接口中沒有提供這種功能的方法,是以我們需要我們自己實作它(還好 TableQuery 的實作支援我們去擴充它)。

本文将通過實作 StartsWith 過濾條件說明如何自定義 Azure Table storage 的查詢過濾條件。

TableQuery類

TableQuery 是本文的主角,它代表了 Table 上的一個查詢。基本用法是使用查詢條件建構一個 TableQuery 類的執行個體,然後把這個執行個體作為參數傳遞給 CloudTable 的 ExecuteQuery 方法:

我們還可以使用 TableQuery 的靜态方法 CombineFilters 建構自定義的查詢條件。

比如我們要查詢 PartitionKey 等于 "201607" 并且 RowKey 等于"161148372454"的記錄:

此時函數的傳回結果為: ” (PartitionKey eq '201607') and (RowKey eq '161148372454')”。

然後把這個過濾字元串送給 query.Where 函數做參數,或者設定給 query.FilterString 屬性,就可以完成過濾功能了。

CombineFilters 方法可愛的地方在于我們可以不斷的使用它來合并查詢條件,直到滿意為止!

接下來我們一起看看 StartsWith 過濾條件的實作過程。

比較字元串

如何從一些字元串中找出以某個子串開頭的字元串呢?我們可以從字元串的比較入手。

比如字元串具有下面的關系:

“abc”  ==  “abc” < “abd”

“abc” < “abca” < “abd”

“abc” < “abcz” < “abd”

由上面的大小關系我們可以得出結論:以”abc”開頭的字元串必定大于或等于”abc”且小于”abd”。OK,這就是我們建構 StartsWith 過濾條件的理論基礎。

建構StartsWith過濾條件

接下來我們通過 TableQuery.CombineFilters 方法建構 StartsWith 過濾條件:

TableQuery.CombineFilters 方法的傳回值是一個字元串。運作上面的代碼我們會得到字元串:

“(RowKey ge 'abc') and (RowKey lt 'abd')”

我們完全可以手動拼出這樣的字元串,但我相信沒有程式員願意這麼做。

那麼,我們需要繼續完善上面的方法:

組合更多過濾條件

在前面建構 StartsWith 過濾條件時,我們已經使用 TableQuery.CombineFilters 方法組合了不同的過濾條件。遺憾的是 TableQuery.CombineFilters 方法隻有兩個參數的重載,我們不能添加更多的 TableOperators 操作。

但我們可以繼續調用 TableQuery.CombineFilters 方法來組合上一個結果和新的條件。比如我們要把 Startswith 過濾條件和 PartitionKey 過濾條件組合起來就可以這麼做:

運作上面的代碼,生成的結果為:

(PartitionKey eq '201607') and ((RowKey ge 'abc') and (RowKey lt 'abd'))

到這來就很清楚了,TableQuery.CombineFilters 方法的主要工作,就是把過濾條件組織成查詢引擎能夠識别的字元串。

因而我們可以通過不斷的疊加,來生成很複雜的過濾條件。

封裝StartsWith過濾條件

下面我們把 StartsWith 的邏輯封裝到 StartsWithByRowKey 類型中,以下是完整的代碼:

應用StartsWith的執行個體

現在查詢 PartitionKey 為”201607”,RowKey 以”16”開頭的記錄可以這麼寫:

代碼簡潔了很多,讀起來也更清晰了(您還可以動手給 PartitionKey 添加同樣的功能)!

小結一下,本文簡單的介紹了 TableQuery 類型,然後比較詳細的說明了 StartsWith 過濾條件的思路及實作。主要是想通過 StartsWith 的實作來說明如何利用現有的類型和方法來實作自定義查詢的過濾條件。對于有類似需求的朋友,希望能起到抛磚引玉的作用。

相關閱讀:

<a href="http://www.cnblogs.com/powertoolsteam/p/Windows_Azure.html">最全的Windows Azure學習教程彙總</a>

<a href="http://www.cnblogs.com/powertoolsteam/p/Azure_Blob_Storage.html" target="_blank">Azure Blob Storage 基本用法 -- Azure Storage 之 Blob</a>

<a href="http://www.cnblogs.com/powertoolsteam/p/Azure_Queue_Storage.html" target="_blank">Azure Queue Storage 基本用法 -- Azure Storage 之 Queue</a>

<a href="http://www.cnblogs.com/powertoolsteam/p/Azure_File_Storage.html" target="_blank">Azure File Storage 基本用法 -- Azure Storage 之 File</a>

<a href="http://www.cnblogs.com/powertoolsteam/p/5707033.html" target="_blank">Azure Table storage 基本用法 -- Azure Storage 之 Table</a>

繼續閱讀