2011-03-23 70 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