我们有一个包含流媒体视频的网站,我们想要显示上周、一个月和一年(滚动窗口)中观看最多的视频的三个报告。
每次观看视频时,我们都会在 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 是错误的;此处的计数不是有效属性。
如有任何帮助,我们将不胜感激。
最佳答案
如果您在 SQL 领域,每个报告都是不同的 GROUP BY,它告诉您需要三个索引 - 一个只有月份,一个按周、一个按月和一个按年(或者也许略有不同,具体取决于您实际执行查询的方式。
现在,您有一个 DateTime - 这会带来一些问题 - 您实际上想要做的是索引 DateTime 的 Year 组件、日期时间的 Month 组件和日期时间的 Day 组件约会时间。 (或者只是其中的一两个,具体取决于您要生成的报告。
我只是在这里引用你的代码,所以显然它不会编译,但是:
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 执行此操作,而且我没有在这台计算机上安装它,因此无法验证这一点,但理论保持不变。
所以,再重申一遍
您想要按周 + 产品 ID 为您的报告建立索引 您想要按月 + 产品 ID 为您的报告建立索引 您想要按年份 + 产品 ID 为您的报告编制索引
我希望这会有所帮助,抱歉我不能给你一个可编译的例子,缺少 raven 让它有点困难:-)
关于c# - Ravendb mapreduce 按多个字段分组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5409769/