6

ストリーミング ビデオを含むサイトがあり、過去 1 週間、1 か月、1 年間 (ローリング ウィンドウ) で最も視聴されたビデオの 3 つのレポートを表示したいと考えています。

ビデオが視聴されるたびにドキュメントを ravendb に保存します。

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

これら 3 つのレポートの生成を最適にサポートするインデックス / mapreduces を定義する方法がわかりません。

次のマップ/リデュースを試しました。

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 は有効なプロパティではありません。

ここで何か助けていただければ幸いです。

4

1 に答える 1

11

SQL ランドにいる場合、各レポートは異なる GROUP BY です。これは、3 つのインデックスが必要であることを示しています。1 つは月のみ、もう 1 つはエントリが週ごと、月ごと、および年ごと (または場合によってはわずかに異なる場合があります) です。実際にクエリを実行する方法について。

ここで、DateTime があり、いくつかの問題があります。実際にやりたいことは、DateTime の Year コンポーネント、日付時刻の Month コンポーネント、およびその DateTime の Day コンポーネントにインデックスを付けることです。(または、生成するレポートに応じて、これらの 1 つまたは 2 つだけです。

ここではコードをパラクォートしているだけなので、明らかにコンパイルされませんが、

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 が必要

これがお役に立てば幸いです。申し訳ありませんが、コンパイル可能な例を提供できません。レイヴンがないため、少し難しくなります:-)

于 2011-03-23T21:48:14.093 に答える