我正在寻找一个如何在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实现这一点.
A map reduce index is just another way of saying "I want to do a group by", only the group by is pre-defined up front and RavenDB will process it in an efficient manner in the background so at query time you are looking up a pre-calculated result.
Consider the following as an answer as an ordinary group by (for unique users)
var results = from doc in docs group doc by doc.UserId into g select new { g.UserId, g.Count() }
Ignoring the actual contents of the created array, we can get the total results by asking for
results.Length
as you'd expect.
In RavenDB, you split out this function into a Map and a Reduce, and you end up with
public class UniqueVisitorsResult { public string UserId { get; set; } public int Count { get; set; } } public class UniqueVisitorsIndex : AbstractIndexCreationTask{ 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) }; } }
In essence, this is the same as the above - but you've turned it into a MapReduce function ;-)
session.Query().Count();
假设Count已在LINQ提供程序中正确实现(iirc,我认为它有),将为您提供唯一访问者的总数
条目总数很简单
session.Query().Count();
正如您所期望的那样(无需地图/减少)
注意:此索引也可用于查看特定用户的点击次数,因为Count正在索引中计算,如果您不关心计数,则删除MapReduce的那部分并执行
public class UniqueVisitorsIndex : AbstractIndexCreationTask{ 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 }; } }
以下是如何为唯一身份访问者构建索引:
public class Statistics_UniqueVisitors : AbstractIndexCreationTask{ 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().Count();
对于访客总数,您可以使用:
var numberOfVisitors = s.Query().Count();