3

我正在使用 RavenDB 来存储一系列事件。这些事件有一个我用来按天分组的日期 (DateTime.Date)。我正在尝试按小时添加一些统计信息,但我似乎无法找到一种干净的方法。

简单的方法:

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)' 的最佳重载方法匹配有一些无效参数行201,位置 72:错误 CS1503 - 参数 2:无法从 'System.Func' 转换为 'System.Func' 行 201,位置 106:错误 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 条记录。我的理解是更大但更少的索引是最好的)?

4

2 回答 2

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 确实存在某种错误。地图应该可以这样写:

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

但由于某种奇怪的原因它失败了。我会将其报告为错误。

是的,与许多小的索引相比,拥有更少的大索引通常更好。

于 2013-11-04T02:06:24.430 回答
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]"
                          }                      
});
于 2013-11-06T22:36:56.120 回答