map reduce index 只是另一种表达“我想做一个 group by”的方式,只有 group by 是预先定义好的,RavenDB 会在后台以有效的方式处理它,所以在查询时你正在查找预先计算的结果。
将以下内容视为普通组的答案(针对唯一用户)
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)
注意:此索引也可用于查看特定用户的点击次数,因为 Count 正在索引中计算,如果您不关心计数,则删除 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
};
}
}