來源:互聯網
上載者:User
關鍵字
Facebook
Azure
行銷式應用程式
Facebook
本文承接《在Azure上構建一個基於Facebook的行銷式應用程式(上) 》 和《在Azure上構建一個基於Facebook的行銷式應用程式(中)》
選擇一個商店
當我們通過了在聯繫資訊上的驗證時,使用者就可以通過自己的喜好選擇一個適合自己的商店。 與此同時,這個應用程式會給使用者提供一個包含三個商店的清單(這三個商店都在這個使用者的郵遞區號所在地方圓50英里之內,是按照從最近到最遠的順序來排序的)。 這三個商店清單要想被快速地顯示出來,並且減少Web角色上的負載,提前計算距離,不僅如此,還要把據距離資訊和商店資料整理到Azure Table Storage中,著一些些複雜的程式都是我們應該考慮到並且提前打好預防針的事情。 不過在此基礎上我們應該瞭解,我們的目標可不是想當然的可升級性或未來的可預見性,那樣只會讓行銷式應用存在的時間變短而已,所以我們的目標是可擴充性。
我使用的是公用的來自于1999年人口普查的美國郵遞區號清單(具體可以參考:HTTP://www.census.gov/geo/www/tiger/zip1999.html)。 這個清單包含每個郵遞區號的經度和緯度座標。 然後,因為我沒有自己的商店,所以我從這個清單隨機地選擇了一些郵遞區號,然後用這些郵遞區號生成了一個包含1000個樣例商店的清單。 然後,把這個商店清單通過CSV檔(這種檔案格式對Azure Azure Storage Explorer比較友好)的形式,上傳到我的第一個Azure表中,「Store」實體如下所示:
Listing 7
public class Store: TableServiceEntity
{
partition key is store number
row key is empty
public Store()
{
this. RowKey = "";
}
public string Name { get; set; }
public string City { get; set; }
public string State { get; set; }
public string Zip { get; set; }
}
接下來,我構建了第二張表,叫作「ZipStore」,對於這個國家中的每個郵遞區號來說,它包含0到3行。 每行是一個「郵遞區號-商店」對,對於每個郵遞區號來說,只考慮在這個郵遞區號所在地方圓50英里內的三個最近的商店。 要構建這樣一張表,我必須要遍歷郵遞區號清單,然後使用一個基於經度和緯度的公式(具體可以參考:HTTP://zips.sourceforge.net/),計算出各個郵遞區號所在地到每一個商店的距離, 把範圍內最近的三個商店保存下來。 如果方圓50英里之內根本就沒有商店,那麼我會放棄這個郵遞區號。 30分鐘的數值分析之後,我得到了一個包含「郵遞區號-商店」資訊的CSV檔,然後我把這個檔上傳到了Azure Table Storage中。 「ZipStore」實體是十分簡單的。
Listing 8
class ZipStore: TableServiceEntity
{
partition key is zip code
row key is distance rank (0 is nearest)
public string StoreNumber { get; set; }
}
「partition key」存儲了郵遞區號。 「row keys」是每個商店的靠近等級。 每個「partition」代表一個郵遞區號,「partition」中的每一行代表一個商店和這個郵遞區號所在地的靠近程度。
現在,我們可以看一看「Store」容器了:
Listing 9
public class StoreRepository : IStoreRepository
{
readonly AzureTable<ZipStore> _zipStore;
readonly AzureTable<Store> _store;
public StoreRepository()
{
var factory = new AzureStorageFactory ();
_zipStore = (AzureTable<ZipStore>)factory. GetTable><ZipStore>();
_store = (AzureTable<Store>)factory. GetTable><Store>();
}
public IEnumerable<Store> GetNearbyStores(string ZipCode)
{
var stores = new List<Store>();
Store store;
var query = _zipStore.Query.Where(zs => zs. PartitionKey == ZipCode);
foreach (ZipStore zs in query)
{
store = _store. Get(s => s.PartitionKey == zs. StoreNumber && s.RowKey == "");
if (store != null)
stores. Add(store);
}
Return stores;
}
}
這裡值得一提的是「GetNearbyStores()」方法,控制器使用這個方法來載入可用的商店清單。 第一個查詢只指定了「partition key」(郵遞區號),然後返回三個或少於三個商店。 因為「row key」是距離等級,所以這個查詢會按照距離的順序來返回各個商店。 而對於每個商店來說,我們使用商店號作為「partition key」,從「store」表中獲取商店名,城市,國家和郵遞區號。
雖然對於這個視圖來說,必須要進行四次查詢,但是它們都是通過「partition key」和「row key」來進行的,速度非常快。 而且,你還可以購買存儲空間,通過把全部的「store」實體都直接存儲到「ZipStore」表中,儘量減少對單一查詢的檢查的方式,來獲得更好的性能。