问题描述
我正在寻找如何在 RavenDB .NET 客户端中实现和使用 Map-Reduce 的示例.
I'm looking for an example of how to implement and use Map-Reduce within the RavenDB .NET Client.
我想将其应用于特定场景:生成唯一身份访问者和总访问者数量.
I'd like to apply it to a specific scenario: generating unique and total visitor counts.
将存储在 RavenDB 中的示例文档:
A sample document that would be stored within RavenDB:
public class StatisticsEntry
{
public string Id { get; set; }
public string UserId { get; set; }
}
我可以弄清楚如何使用 Map 创建标准索引,但我不知道如何实际使用 Reduce 函数,然后检索结果.
I can figure out how to create a standard index using Map, but I'm lost as to how to actually use the Reduce function, and then retrieve the results.
不幸的是,RavenDB 站点上提供的示例 没有解释发生了什么,所以我可以理解如何通过 .NET API 使用它,并且示例似乎根本没有使用 .NET API 实现这一点.
Unfortunately, the example provided on the RavenDB Site doesn't explain what's going on so that I can understand how to use it via the .NET API, and the samples don't seem to implement this at all using the .NET API.
推荐答案
map reduce index 只是我想做一个 group by"的另一种说法,只有 group by 是预先定义好的,RavenDB 会在后台以有效的方式处理它,因此在查询时您正在查找预先计算的结果.
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
如你所愿.
在 RavenDB 中,您将此函数拆分为 Map 和 Reduce,最终得到
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)
};
}
}
本质上,这和上面的一样——但是你已经把它变成了一个 MapReduce 函数;-)
In essence, this is the same as the above - but you've turned it into a MapReduce function ;-)
session.Query<StatisticEntry, UniqueVisitorsIndex>().Count();
假设已在 LINQ 提供程序中正确实现了 Count(我认为是 iirc),将为您提供唯一访问者的总数
Will give you the total number of unique visitors, assuming Count has been implemented properly in the LINQ provider (iirc I think it has)
总条目数简直就是
session.Query<StatisticEntry>().Count();
如您所料(无需 map/reduce)
As you'd expect (No map/reduce required)
注意:此索引也可用于查看特定用户的点击次数,因为 Count 正在索引中计算,如果您不关心计数,则删除 MapReduce 的那部分并执行
Note: this index can also be used to see the number of hits by a specific user, as the Count is being calculated in the index, if you don't care about the count then drop that part of the MapReduce and do
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
};
}
}
这篇关于使用 .NET 客户端的 RavenDB Map-Reduce 示例的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!