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
};
}
}