2015-07-12 20 views
0

我有一個Azure的表存儲表結構爲:LINQ的命令來查找在Azure Table中存儲的差異項

id date_changed entity_1 entity_2 
1  May 1 2015  true  false 
2  May 2 2015  false  true 
3  May 3 2015  false  false 
4  May 4 2015  true  false 
5  May 5 2015  false  true 
6  May 7 2015  true  false 

我試圖找到一種方法來拉出只有那些entity_1已經改變記錄隨着時間的推移(date_changed)。 例如,如果我想回到這裏entity_1無論從false → truetrue → false改變date_changed增加的記錄:

2  May 2 2015  false  true 
4  May 4 2015  true  false 
5  May 5 2015  false  true 
6  May 7 2015  true  false 

或爲entity_2

2  May 2 2015  false  true 
3  May 3 2015  false  false 
5  May 5 2015  false  true 
6  May 7 2015  true  false 

我當然可以用一個循環做到這一點,但這不會真正縮放,因爲我必須遍歷所有記錄,並且隨着我的表增加記錄,這似乎不可行。

有沒有一種方法來創建LINQ查詢來查詢表存儲只返回那些記錄,entity_1entity_2變化date_changed增加?

+0

你插入每個實體當天更改的記錄?我的意思是,今天是7月12日。當時鍾在7月13日到達時,你是否在表中爲所有實體以其當前狀態(真或假)插入新記錄?隨着時間的推移,如果實體狀態發生變化,您是否更新這些實體?然後在第二天再次插入新記錄?另外請介紹一下你的PartitionKey/RowKey值。 –

+0

不一定每天插入記錄,但在同一天(即可能每天,也可能每隔一天等)插入多個記錄。 'PartitianKey'是一個userid(所以假設上面的例子都具有相同的'PartitianKey''''' RowKey'''是一個簡單的'GUID'. – Brett

+0

這裏有一個想法:你使用entity ids作爲分區鍵和反時間(最大時間 - 當前日期)作爲行鍵,因此每個實體最終將在不同的分區中,最近的更新將始終位於最前面,每當添加一個新更新時,都會有一個額外的字段作爲變化的指示符。最近的更新將會非常高效。在一組分區中的查詢將具有高吞吐量。 – mert

回答

0

沒有辦法以可伸縮的方式使用像Azure Table這樣的鍵值NoSQL數據庫服務實現所請求的功能。我建議的解決方案是創建兩個新表,Entity1TransitionTable和Entity2TransitionTable。該提議是在Azure Table存儲相對便宜的前提下,即時檢測轉換並維護這些表中的轉換列表。該解決方案假定應用程序可以隨時跟蹤的ID值,它總是由1

public class LogEntry : TableEntity 
    { 
    public LogEntry() { } 
    public LogEntry(string userid, int id, string date, bool entity1, bool entity2) 
    { 
     PartitionKey = userid; 
     RowKey = id.ToString(); 
     Id = id; 
     Entity1 = entity1; 
     Entity2 = entity2; 
     Date = date; 
    } 
    public int Id { get; set; } 
    public string Date { get; set; } 
    public bool Entity1 { get; set; }   
    public bool Entity2 { get; set; }   
    } 

    static void TransitionDetection(CloudTable tbl, CloudTable e1Tbl, CloudTable e2Tbl, LogEntry currentLogEntry) 
    { 
    if (currentLogEntry.Id> 1) 
    { 
     // Retrieve the previous log entry 
     string pkFilter = TableQuery.GenerateFilterCondition("PartitionKey", QueryComparisons.Equal, currentLogEntry.PartitionKey); 
     string rkFilter = TableQuery.GenerateFilterCondition("RowKey", QueryComparisons.Equal, (currentLogEntry.Id - 1).ToString()); 
     string combinedFilter = TableQuery.CombineFilters(pkFilter, TableOperators.And, rkFilter); 
     TableQuery<LogEntry> query = new TableQuery<LogEntry>().Where(combinedFilter); 
     LogEntry prevLogEntry = tbl.ExecuteQuery(query).ToList()[0]; 

     // If Entity1 transitioned, record it 
     if (prevLogEntry.Entity1 != currentLogEntry.Entity1) 
     { 
      e1Tbl.Execute(TableOperation.Insert(currentLogEntry)); 
     } 

     // If Entity2 transitioned, record it 
     if (prevLogEntry.Entity2 != currentLogEntry.Entity2) 
     { 
      e2Tbl.Execute(TableOperation.Insert(currentLogEntry)); 
     } 
    } 
    } 

    static void Main(string[] args) 
    { 
    string storageConnection = "DefaultEndpointsProtocol=https;AccountName=MyTable;AccountKey=MY_KEY"; 

    // Select table 
    CloudStorageAccount storageAccount = CloudStorageAccount.Parse(storageConnection); 
    CloudTableClient tableClient = storageAccount.CreateCloudTableClient(); 
    CloudTable table = tableClient.GetTableReference("LogTable"); 
    CloudTable entity1TransitionTable = tableClient.GetTableReference("Entity1TransitionTable"); 
    CloudTable entity2TransitionTable = tableClient.GetTableReference("Entity2TransitionTable"); 
    table.CreateIfNotExists(); 
    entity1TransitionTable.CreateIfNotExists(); 
    entity2TransitionTable.CreateIfNotExists(); 

    // Add Log Entries 
    int id = 0; 

    LogEntry le1 = new LogEntry("0", ++id, "May 1 2015", true, false); 
    TransitionDetection(table, entity1TransitionTable, entity2TransitionTable, le1); 
    table.Execute(TableOperation.Insert(le1)); 

    LogEntry le2 = new LogEntry("0", ++id, "May 2 2015", false, true); 
    TransitionDetection(table, entity1TransitionTable, entity2TransitionTable, le2); 
    table.Execute(TableOperation.Insert(le2)); 

    LogEntry le3 = new LogEntry("0", ++id, "May 3 2015", false, false); 
    TransitionDetection(table, entity1TransitionTable, entity2TransitionTable, le3); 
    table.Execute(TableOperation.Insert(le3)); 

    LogEntry le4 = new LogEntry("0", ++id, "May 4 2015", true, false); 
    TransitionDetection(table, entity1TransitionTable, entity2TransitionTable, le4); 
    table.Execute(TableOperation.Insert(le4)); 

    LogEntry le5 = new LogEntry("0", ++id, "May 5 2015", false, true); 
    TransitionDetection(table, entity1TransitionTable, entity2TransitionTable, le5); 
    table.Execute(TableOperation.Insert(le5)); 

    LogEntry le6 = new LogEntry("0", ++id, "May 7 2015", true, false); 
    TransitionDetection(table, entity1TransitionTable, entity2TransitionTable, le6); 
    table.Execute(TableOperation.Insert(le6)); 

    Console.ReadKey(); 
    } 

遞增如果您檢查與像TableXplorer申請表,你會看到下面的結果:

LogTable

enter image description here

Entity1TransitionTable

enter image description here

Entity2TransitionTable