22

RavenDB .NET クライアント内で Map-Reduce を実装して使用する方法の例を探しています。

これを特定のシナリオに適用したいと思います。つまり、一意の訪問者数と合計訪問者数を生成します。

RavenDB 内に保存されるサンプル ドキュメント:

public class StatisticsEntry
{
    public string Id { get; set; }
    public string UserId { get; set; }
}

Map を使用して標準的なインデックスを作成する方法は理解できますが、Reduce 関数を実際に使用して結果を取得する方法についてはわかりません。

残念ながら、RavenDB サイトで提供されている例では、.NET API を介して使用する方法を理解できるように、何が起こっているかを説明していません。サンプルは、.NET API を使用してこれをまったく実装していないようです。

4

2 に答える 2

38

map reduce インデックスは、「group by を実行したい」という別の言い方です。group by のみが前もって定義されており、RavenDB はバックグラウンドで効率的な方法でそれを処理するため、クエリ時に検索します。事前に計算された結果。

通常の group by (ユニークユーザー向け) として、以下を回答と考えてください。

 var results = from doc in docs
 group doc by doc.UserId into g
 select new
 {
      g.UserId,
      g.Count()
 }

作成された配列の実際の内容を無視して、次のように求めることで合計結果を取得できます。

 results.Length

あなたが期待するように。

RavenDB では、この関数を Map と Reduce に分割すると、最終的に次のようになります。

public class UniqueVisitorsResult
{
     public string UserId { get; set; }
     public int Count { get; set; }
}

public class UniqueVisitorsIndex : AbstractIndexCreationTask<StatisticsEntry, UniqueVisitorsResult>
{
    public UniqueVisitorsIndex ()
    {
        Map = docs=> from doc in docs
                         select new 
                         { 
                             UserId = doc.UserId, 
                             Count = 1 
                         };
        Reduce = results => from result in results
                        group result by result.UserId into g
                        select new 
                        { 
                            UserId = g.Key, 
                            Count = g.Sum(x=>x.Count) 
                        };
    }
}

本質的に、これは上記と同じですが、MapReduce 関数に変換しています ;-)

 session.Query<StatisticEntry, UniqueVisitorsIndex>().Count();

Count が LINQ プロバイダーに適切に実装されていると仮定すると、一意の訪問者の総数が得られます (iirc は実装されていると思います)。

エントリー総数は単純に

 session.Query<StatisticEntry>().Count();

ご想像のとおり (map/reduce は不要)

注: このインデックスを使用して、特定のユーザーによるヒット数を確認することもできます。これは、カウントがインデックスで計算されているためです。カウントを気にしない場合は、MapReduce のその部分を削除して実行します。

public class UniqueVisitorsIndex : AbstractIndexCreationTask<StatisticsEntry>
{
    public UniqueVisitorsIndex ()
    {
        Map = docs=> from doc in docs
                     select new 
                     { 
                         UserId = doc.UserId
                     };
        Reduce = results => from result in results
                    group result by result.UserId into g
                    select new 
                    { 
                        UserId = g.Key
                    };
    }
}
于 2010-11-23T10:44:50.697 に答える
18

ユニークな訪問者のインデックスを作成する方法は次のとおりです。

public class Statistics_UniqueVisitors : AbstractIndexCreationTask<StatisticsEntry>
{
    public Statistics_UniqueVisitors()
    {
        Map = entries => from entry in entries
                         select new { entry.UserId, Count = 1 };
        Reduce = results => from result in results
                            group result by result.UserId into g
                            select new { UserId = g.Key, Count = g.Sum(x=>x.Count) };
    }
}

次に、以下を使用してこれを照会できます。

var numberOfUniqueVisitors = s.Query<StatisticEntry, Statistics_UniqueVisitors>().Count();

訪問者の総数については、次を使用できます。

var numberOfVisitors = s.Query<StatisticEntry>().Count();
于 2010-11-23T10:39:33.097 に答える