2011-03-23 69 views
6

我们有一个包含流式视频的网站,我们希望在上周,月和年(滚动窗口)中显示三个最受关注视频的报告。Ravendb mapreduce按多个字段分组

我们存储在ravendb观看视频的每一次文件:

public class ViewedContent 
{ 
    public string Id { get; set; } 
    public int ProductId { get; set; } 
    public DateTime DateViewed { get; set; } 
} 

我们遇到了麻烦搞清楚如何定义索引/ mapreduces能最好地支持生成这三个报告。

我们尝试了下面的map/reduce。

public class ViewedContentResult 
{ 
    public int ProductId { get; set; } 
    public DateTime DateViewed { get; set; } 
    public int Count { get; set; } 
} 

public class ViewedContentIndex : 
     AbstractIndexCreationTask<ViewedContent, ViewedContentResult> 
{ 
    public ViewedContentIndex() 
    { 
     Map = docs => from doc in docs 
         select new 
           { 
            doc.ProductId, 
            DateViewed = doc.DateViewed.Date, 
            Count = 1 
           }; 

     Reduce = results => from result in results 
          group result by result.DateViewed 
          into agg 
          select new 
             { 
              ProductId = agg.Key, 
              Count = agg.Sum(x => x.Count) 
             }; 
    } 
} 

但是,这个查询将引发一个错误:

var lastSevenDays = session.Query<ViewedContent, ViewedContentIndex>() 
       .Where(x => x.DateViewed > DateTime.UtcNow.Date.AddDays(-7)); 

Error: "DateViewed is not indexed"

最终,我们要查询类似:

var lastSevenDays = session.Query<ViewedContent, ViewedContentIndex>() 
       .Where(x => x.DateViewed > DateTime.UtcNow.Date.AddDays(-7)) 
       .GroupBy(x => x.ProductId) 
       .OrderBy(x => x.Count) 

这并不实际编译,因为OrderBy是错误的; Count在这里不是一个有效的属性。

任何帮助在这里将不胜感激。

回答

9

如果你在SQL的土地上,每个报表都是不同的GROUP BY,它告诉你需要三个索引 - 一个只有一个月,一个按周,一个月,一年一个可能会稍微有所不同,具体取决于你如何进行查询

现在,你有一个日期时间那里 - 存在一些问题 - 实际上想要做的是索引DateTime的Year元件,日期时间的月份组件和日期时间的日期组件(或者只是其中的一个或两个,具体取决于您想要生成哪个报表)

我只是对位引用在这里你的代码,所以显然它不会编译,但:

public class ViewedContentIndex : 
    AbstractIndexCreationTask<ViewedContent, ViewedContentResult> 
{ 
public ViewedContentIndex() 
{ 
    Map = docs => from doc in docs 
        select new 
          { 
           doc.ProductId, 
           Day = doc.DateViewed.Day, 
           Month = doc.DateViewed.Month, 
           Year = doc.DateViewed.Year 
           Count = 1 
          }; 

    Reduce = results => from result in results 
         group result by new { 
          doc.ProductId, 
          doc.DateViewed.Day, 
          doc.DateViewed.Month, 
          doc.DateViewed.Year 
         } 
         into agg 
         select new 
            { 
             ProductId = agg.Key.ProductId, 
             Day = agg.Key.Day, 
             Month = agg.Key.Month, 
             Year = agg.Key.Year 
             Count = agg.Sum(x => x.Count) 
            }; 
} 

}

希望你能看到什么,我试图通过这个实现 - 您希望您的组中的所有组件,他们是什么让你的分组独特。

我不记得RavenDB是否可以用DateTimes做到这一点,而且我没有在这台计算机上得到它,所以无法验证这一点,但理论依然如此。

因此,再次重申

你想通过周+产品编号 报告索引您想为按月+产品编号 报告索引您想要在今年报告的指数+产品编号

我希望这可以帮助,对不起,我不能给你一个编译例如,缺乏乌鸦使得它有点困难:-)

+0

是的,这是它!这里的心理转变是看到我可以将一个物体而不仅仅是一个物体组合在一起。最终,我们必须查询日期的滚动窗口。但是,这正是我所需要的。再次感谢! – 2011-03-23 23:36:13