【问题标题】:Ravendb mapreduce grouping by multiple fieldsRavendb mapreduce 按多个字段分组
【发布时间】:2011-03-24 05:48:14
【问题描述】:

我们有一个包含流媒体视频的网站,我们希望显示上周、月和年(滚动窗口)中观看次数最多的视频的三份报告。

每次观看视频时,我们都会在 ravendb 中存储一个文档:

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

我们无法确定如何定义最能支持生成这三个报告的索引/mapreduce。

我们尝试了下面的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) );

错误:“DateViewed 未编入索引”

最终,我们想要查询如下内容:

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 属性无效。

如有任何帮助,我们将不胜感激。

【问题讨论】:

    标签: c# mapreduce ravendb


    【解决方案1】:

    如果您在 SQL 领域,每个报告都是不同的 GROUP BY,它告诉您需要三个索引 - 一个仅包含月份,一个包含每周条目,一个按月,一个按年份(或者可能根据您实际执行查询的方式略有不同。

    现在,您在那里有一个 DateTime - 这会带来一些问题 - 您实际上想要做的是索引 DateTime 的 Year 组件、日期时间的 Month 组件和该 DateTime 的 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 会有点困难 :-)

    【讨论】:

    • 是的,就是这样!这里的精神转变是看到我可以在一个对象上分组,而不仅仅是一个场。最终,我们必须查询日期的滚动窗口。但是,这正是我所需要的。再次感谢!
    猜你喜欢
    • 1970-01-01
    • 2018-11-28
    • 2013-08-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-05-20
    相关资源
    最近更新 更多