2013-11-03 34 views
3

我使用RavenDB存儲事件集合。這些事件有一個我正在使用的日期分組日期(DateTime.Date)。我試圖按小時添加一些統計信息,但我似乎無法找到一種乾淨利落的方法。使用RavenDB索引按小時計數

簡單的方法:

public class DailyStats : AbstractIndexCreationTask<Incident, DateStat> 
{ 
    public DailyStats() 
    { 
     Map = docs => from doc in docs 
         select new 
           { 
            doc.OccuredOn, 
            Hour0 = doc.OccuredOn.Hour == 0 ? 1 : 0 
            Hour1 = doc.OccuredOn.Hour == 1 ? 1 : 0 
            //.... 
           }; 

     Reduce = mapped => from m in mapped 
          group m by new { m.Date.Date } 
          into g 
          select new 
             { 
              g.Key.Date, 
              Hour0 = g.Sum(x => x.Hour0), 
              Hour1 = g.Sum(x => x.Hour1) 
              //.... 
             } 
    } 
} 

但是這是可怕的重複。相反,我試圖用一個字典:

public class DailyStats : AbstractIndexCreationTask<Incident, DateStat> 
{ 
    public DailyStats() 
    { 
     Map = docs => from doc in docs 
         select new 
           { 
            doc.OccuredOn, 
            IncidentsByHour = Enumerable.Range(0, 24).ToDictionary(h => h, h => doc.IncidentDate.Hour == h ? 1 : 0), 
           }; 

     Reduce = mapped => from m in mapped 
          group m by new { m.Date.Date } 
          into g 
          select new 
             { 
              g.Key.Date, 
              IncidentsByHour = Enumerable.Range(0, 24).Select(h => g.Sum(x => x.IncidentsByHour[h])), 
             } 
    } 
} 

會拋出異常:

201線,22位:錯誤CS1502 - 爲「System.Linq.Enumerable的最佳重載的方法匹配.ToDictionary(System.Collections.Generic.IEnumerable,System.Func,System.Collections.Generic.IEqualityComparer)'有一些無效參數 Line 201,Position 72:Error CS1503 - 參數2:無法從'System.Func'轉換爲'System.Func' Line 201,Position 106:Error CS1503 - 參數3:無法從'System.Func'轉換爲'System.Collections.Generic.IEqualityComparer' 行274,位置22:錯誤CS1928 - 'System.Collections.Generic.IEnumerable'不包含'Select'和最佳擴展方法重載'System.Linq.Enumerable.Select(System.Collections.Generic.IEnumerable ,System.Func)」有一些無效參數274 線,位置54:錯誤CS1503 - 參數2:不能轉換 'System.Func' 到 'System.Func'

我不知道如何解決這個異常,因爲它發生在Raven方面。

白天分組的原因是我需要拉365天的統計數據,但仍然有一些小時的基本信息。如果有兩個索引,一天一個,一個一個小時(對於總共365 + 24條記錄加載,我的理解是更大但更少的索引是最好的),會更好嗎?

回答

2

試試這個:

public class DailyStats : AbstractIndexCreationTask<Incident, DateStat> 
{ 
    public DailyStats() 
    { 
    Map = docs => 
     from doc in docs 
     select new 
     { 
     Date = doc.OccuredOn, 
     IncidentsByHour = new Dictionary<int, int> { { doc.OccuredOn.Hour, 1 } } 
     }; 

    Reduce = mapped => 
     from m in mapped 
     group m by new { m.Date.Date } 
     into g 
     select new 
     { 
     Date = g.Key, 
     IncidentsByHour = g.SelectMany(x => x.IncidentsByHour) 
          .GroupBy(x => x.Key) 
          .OrderBy(x => x.Key) 
          .ToDictionary(x => x.Key, x => x.Sum(y => y.Value)) 
     }; 
    } 
} 

這裏唯一的區別是,你不會得到你的詞典中的任何物品有沒有事故小時。

Raven的確還存在一些bug。地圖應該能夠與這個被寫成:

IncidentsByHour = Enumerable.Range(0, 24) 
         .ToDictionary(h => h, h => doc.OccuredOn.Hour == h ? 1 : 0) 

但它沒有一些奇怪的原因。我會將其報告爲一個錯誤。

是的,通常比許多小型指數更少的指數更好。

+0

記錄爲[RavenDB-1461](http://issues.hibernatingrhinos.com/issue/RavenDB-1461) –

+0

完美,謝謝你。這是一個巨大的改進,我可以處理客戶端丟失的時間。 – mfanto

1

根據你希望你的結果看起來像什麼,你可以嘗試一個分面搜索。 http://ravendb.net/docs/2.5/client-api/faceted-search

顯然,如果你已經深入到了一天,你對這個有興趣只會工作我還要寫代碼來生成的範圍內,但它看起來像下面這樣:

var myCoolStuff = session.Query<Incident, SomeIndex>().Where().ToFacet(
new List<Facet> 
      { 
       new Facet 
        { 
         Name = "OccuredOn" 
         Mode = FacetMode.Ranges, 
         Ranges = 
          { 
           "[2013-01-01T00:00 TO 2013-01-01T01:00]", 
           "[2013-01-01T01:00 TO 2013-01-01T02:00]", 
           "[2013-01-01T02:00 TO 2013-01-01T03:00]", 
           "[2013-01-01T03:00 TO 2013-01-01T04:00]", 
           "[2013-01-01T04:00 TO 2013-01-01T05:00]", 
           "[2013-01-01T05:00 TO 2013-01-01T06:00]", 
           "[2013-01-01T06:00 TO 2013-01-01T07:00]", 
           "[2013-01-01T07:00 TO 2013-01-01T08:00]", 
           "[2013-01-01T08:00 TO 2013-01-01T09:00]", 
           "[2013-01-01T09:00 TO 2013-01-01T10:00]", 
           "[2013-01-01T10:00 TO 2013-01-01T11:00]", 
           "[2013-01-01T11:00 TO 2013-01-01T12:00]", 
           "[2013-01-01T12:00 TO 2013-01-01T13:00]", 
           "[2013-01-01T13:00 TO 2013-01-01T14:00]", 
           "[2013-01-01T14:00 TO 2013-01-01T15:00]", 
           "[2013-01-01T15:00 TO 2013-01-01T16:00]", 
           "[2013-01-01T16:00 TO 2013-01-01T17:00]", 
           "[2013-01-01T17:00 TO 2013-01-01T18:00]", 
           "[2013-01-01T18:00 TO 2013-01-01T19:00]", 
           "[2013-01-01T19:00 TO 2013-01-01T20:00]", 
           "[2013-01-01T20:00 TO 2013-01-01T21:00]", 
           "[2013-01-01T21:00 TO 2013-01-01T22:00]", 
           "[2013-01-01T22:00 TO 2013-01-01T23:00]", 
           "[2013-01-01T23:00 TO 2013-01-02T00:00]" 
          }      
});