2016-02-13 44 views
2

我想查詢文檔上的更新時間戳記_ts以獲取自某個時間段以來未發生變化的文檔。DocumentDB如何在_TS上進行LINQ查詢?

當我創建了蔚藍色的門戶網站這個工作的選擇查詢:

SELECT TOP 10 c.id FROM c WHERE c._ts < 6.35909919217878E+17 

的怪異號與日期時間對象創建的蜱,見下文。

但是,當我嘗試通過LINQ創建它時,它不會執行,因爲您沒有_ts,而是將Timestamp作爲DateTime對象。當我嘗試輸入完整的DateTime對象來與Timestamp進行比較時,它會崩潰,並說它不支持它。所以,我試試這個:

DocRepo.Get(x => x.Timestamp.Ticks < CloseDate.Ticks); 

這導致到什麼,當我觀看了查詢執行它有這個作爲一個選擇查詢:

SELECT * FROM root WHERE root[\"_ts\"][\"Ticks\"] < 6.35909943137688E+17 

是否有可能在_TS時間戳查詢還是我必須有一個額外的updatedAt字段來做到這一點,這似乎是多餘的。

回答

4

你的查詢有幾個問題。在您的第一個查詢中,您正在比較「蜱」(百萬分之一秒 - see here)與_ts值,這很可能會返回集合中的所有文檔,因爲_ts值是以秒爲單位測量的POSIX(Unix)時間see here。他們也不是基於同一個時代。 Unix值從午夜1,1,1970開始,其中Ticks從午夜開始1,1,0001因此,_ts值總是比Ticks值小得多(不要提到1969年!)。您需要將日期轉換爲Unix時間值。你可以創建一個擴展方法來幫助你做到這一點:

public static long ToUnixTime(this DateTime date) 
    { 
     var epoch = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc); 
     return (long)(date - epoch).TotalSeconds; 
    } 

對於LINQ的聲明,你不能(不幸)把日期時間爲LINQ查詢,因爲DateTime值不會轉換爲一個常量(這是你得到的錯誤)。因此,在這兩種情況下,您都不能很容易地比較_ts值或TimeStamp值。

那該怎麼辦?那麼,在看DocumentDB SDK,如果你看一下時間戳的定義,你會看到以下內容:

// Summary: 
    //  Gets the last modified timestamp associated with the resource. 
    [JsonConverter(typeof(UnixDateTimeConverter))] 
    [JsonProperty(PropertyName = "_ts")] 
    public virtual DateTime Timestamp { get; internal set; } 

所以默認情況下,SDK是_TS值轉換爲DateTime,並通過時間戳字段將它暴露。根據您的DocRepo返回的類型,您可以執行一些操作。如果是默認的文件類型,你可以創建一個新的類,從的Docment型像這樣繼承:

public class MyDocument : Document 
{ 
    public long _ts 
    { 
     get; set; 
    } 
} 

如果這是你自己的自定義類,然後就在_TS字段添加到您的類。無論哪種方式,如果_ts字段存在,DocumentDB將填充該字段。然後,如果您添加ToUnixTime擴展方法,你可以撰寫你的Linq查詢是這樣的:

DocRepo.Get(x => x._ts < CloseDate.ToUnixTime()); 

這可能不是一個完美的解決方案,有人(希望)可能會拿出一個更好的解決辦法,但我已驗證它對我自己的DocumentDB集合有效。

希望這會有所幫助。

0

這是我使用Unix時間戳轉換成DateTime格式,我們可以在C#中很容易理解:

public DateTime TimeStamp 
     {    
      get 
      { 
       return DateTimeOffset.FromUnixTimeSeconds(int.Parse(_ts)).DateTime; 
      } 
     } 

希望這有助於。