使用.NET客户端的RavenDB Map-Reduce示例

时间:2010-11-23 06:24:52

标签: .net mapreduce ravendb

我正在寻找一个如何在RavenDB .NET Client中实现和使用Map-Reduce的示例。

我想将它应用于特定场景:生成唯一和总访问者数量。

将存储在RavenDB中的示例文档:

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

我可以弄清楚如何使用Map创建标准索引,但是我对如何实际使用Reduce函数,然后检索结果感到迷茫。

不幸的是,example provided on the RavenDB Site没有解释发生了什么,所以我可以理解如何通过.NET API使用它,并且样本似乎根本不使用.NET API来实现它。

2 个答案:

答案 0 :(得分:38)

地图缩小索引只是说“我想要分组”的另一种方式,只有预先定义的分组,而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();

正如您所期望的那样(无需地图/减少)

注意:此索引也可用于查看特定用户的点击次数,因为正在计算索引中的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
                    };
    }
}

答案 1 :(得分: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();