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

22 .net mapreduce ravendb

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

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

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

public class StatisticsEntry
{
    public string Id { get; set; }
    public string UserId { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

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

遗憾的是,RavenDB网站提供示例并没有解释发生了什么,因此我可以通过.NET API了解如何使用它,并且示例似乎根本不使用.NET API实现这一点.

Rob*_*ton 38

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()
 }
Run Code Online (Sandbox Code Playgroud)

Ignoring the actual contents of the created array, we can get the total results by asking for

 results.Length
Run Code Online (Sandbox Code Playgroud)

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<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) 
                        };
    }
}
Run Code Online (Sandbox Code Playgroud)

In essence, this is the same as the above - but you've turned it into a MapReduce function ;-)

 session.Query<StatisticEntry, UniqueVisitorsIndex>().Count();
Run Code Online (Sandbox Code Playgroud)

假设Count已在LINQ提供程序中正确实现(iirc,我认为它有),将为您提供唯一访问者的总数

条目总数很简单

 session.Query<StatisticEntry>().Count();
Run Code Online (Sandbox Code Playgroud)

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

注意:此索引也可用于查看特定用户的点击次数,因为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
                    };
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 和安装这个索引的关键?`Raven.Client.Indexes.IndexCreation.CreateIndexes(typeof(UniqueVisitorsIndex).Assembly,documentStore);` - 带我一点挖掘找到那个.:) (7认同)

Aye*_*ien 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) };
    }
}
Run Code Online (Sandbox Code Playgroud)

然后您可以使用以下方法查询:

var numberOfUniqueVisitors = s.Query<StatisticEntry, Statistics_UniqueVisitors>().Count();
Run Code Online (Sandbox Code Playgroud)

对于访客总数,您可以使用:

var numberOfVisitors = s.Query<StatisticEntry>().Count();
Run Code Online (Sandbox Code Playgroud)