RavenDB Map-Reduce Beispiel unter Verwendung von .NET-Client
Frage
Ich suche ein Beispiel dafür, wie zu implementieren und verwenden Map-Reduce im RavenDB .NET-Client.
Ich möchte es auf ein bestimmtes Szenario anzuwenden: Erzeugen von einmaligen und Gesamt Besucher zählt.
Ein Beispieldokument, das in RavenDB gespeichert werden würde:
public class StatisticsEntry
{
public string Id { get; set; }
public string UserId { get; set; }
}
kann ich herausfinden, wie ein Standard-Index mit Map erstellen, aber ich bin verloren, wie eigentlich die Funktion reduzieren, verwenden und dann die Ergebnisse abzurufen.
Leider ist das Beispiel auf der Website zur Verfügung gestellt RavenDB nicht erklären, was so los ist das kann ich verstehen, wie es über die .NET-API zu verwenden, und die Proben scheinen nicht die überhaupt API mit .NET zu implementieren.
Lösung
Eine Karte Index zu reduzieren, ist nur eine andere Art zu sagen: „Ich möchte eine Gruppe tun, indem sie“, nur die Gruppe von vordefiniert vorne und RavenDB wird es auf effiziente Weise im Hintergrund, sodass zum Zeitpunkt der Abfrage verarbeiten Sie suchen, um ein vorausberechnete Ergebnis auf.
Betrachten Sie das folgende als eine Antwort als eine gewöhnliche Gruppe von (für Unique User)
var results = from doc in docs
group doc by doc.UserId into g
select new
{
g.UserId,
g.Count()
}
den eigentlichen Inhalt des erstellten Array Ignorieren, können wir die Gesamtergebnisse erhalten, indem für die Nachfrage
results.Length
als man erwarten würde.
In RavenDB, Sie spalten sich diese Funktion in einer Karte und einem Reduce, und Sie am Ende mit
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)
};
}
}
Im Wesentlichen ist dies das gleiche wie die oben - aber Sie es in eine MapReduce-Funktion aktiviert haben; -)
session.Query<StatisticEntry, UniqueVisitorsIndex>().Count();
Wollen Sie die Gesamtzahl der Besucher geben, Graf angenommen wurde ordnungsgemäß in der LINQ-Provider implementiert (iirc ich denke, es hat)
Die Gesamtzahl der Einträge ist einfach
session.Query<StatisticEntry>().Count();
Wie zu erwarten ist (No Map / Reduce erforderlich)
Hinweis: Dieser Index kann auch verwendet werden, um die Anzahl der Zugriffe von einem bestimmten Benutzer zu sehen, wie der Graf im Index berechnet wird, wenn Sie nicht über die Zählung kümmern fällt dann, dass ein Teil des MapReduce und tut
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
};
}
}
Andere Tipps
Hier ist, wie Sie einen Index für Besucher aufbauen können:
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) };
}
}
Sie können dann abfragen, dies mit:
var numberOfUniqueVisitors = s.Query<StatisticEntry, Statistics_UniqueVisitors>().Count();
Für Gesamtzahl der Besucher, die Sie verwenden können:
var numberOfVisitors = s.Query<StatisticEntry>().Count();