Skip to content

Instantly share code, notes, and snippets.

@contactsamie
Forked from mouhong/DocStore.cs
Created May 13, 2020 09:47
Show Gist options
  • Select an option

  • Save contactsamie/3ce8de160bab967c4fadbb35315861c2 to your computer and use it in GitHub Desktop.

Select an option

Save contactsamie/3ce8de160bab967c4fadbb35315861c2 to your computer and use it in GitHub Desktop.
RavenDB Multi-Map/Reduce VisitSummaryByDateIndex
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Raven.Client;
using Raven.Client.Document;
using Raven.Client.Indexes;
namespace RavenTest
{
public static class DocStore
{
public static IDocumentStore Store { get; private set; }
public static void Initialize()
{
var store = new DocumentStore();
store.ConnectionStringName = "RavenDB";
store.Initialize();
IndexCreation.CreateIndexes(typeof(DocStore).Assembly, store);
Store = store;
}
public static IDocumentSession OpenSession()
{
return Store.OpenSession();
}
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace RavenTest
{
public class PageVisit
{
public int Id { get; set; }
public string SessionId { get; set; }
public DateTime VisitTime { get; set; }
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using RavenTest.Index;
namespace RavenTest
{
class Program
{
static void Main(string[] args)
{
DocStore.Initialize();
// Step 1: Generate Sample Data
// GenerateSampleData();
// Step 2: Query index result (in the result, TotalUniqueVisitors are all zero, this is incorrect!)
Console.WriteLine("Date\tSessions\tUniqueVisitors\tNewVisitors\tPageVisits");
using (var session = DocStore.OpenSession())
{
foreach (var each in session.Query<VisitSummaryByDate, VisitSummaryByDateIndex>().OrderBy(it => it.Date))
{
Console.WriteLine(each.Date.ToString("MM-dd") + "\t" + each.TotalVisitSessions + "\t" + each.TotalUniqueVisitors + "\t" + each.TotalNewVisitors + "\t" + each.TotalPageVisits);
}
}
Console.WriteLine("OK");
Console.ReadKey();
}
static void GenerateSampleData()
{
GenerateSampleDataForDate(new DateTime(2012, 5, 10), 10, 5);
GenerateSampleDataForDate(new DateTime(2012, 5, 11), 15, 4);
GenerateSampleDataForDate(new DateTime(2012, 5, 12), 12, 5);
}
static void GenerateSampleDataForDate(DateTime date, int sessionCount, int uniqueVisitorCount)
{
var uniqueVisitorIds = new List<string>();
for (var i = 0; i < uniqueVisitorCount; i++)
{
uniqueVisitorIds.Add("UniqueVisitorId_" + (i + 1));
}
var ravenSession = DocStore.OpenSession();
for (var i = 0; i < sessionCount; i++)
{
var sessionId = "Session_" + date.ToString("yyyy_MM_dd_") + (i + 1);
var session = new VisitSession
{
SessionId = sessionId,
StartTime = date.AddMinutes(i + 1),
IsNewVisit = i < uniqueVisitorCount,
UniqueVisitorId = uniqueVisitorIds[i % uniqueVisitorCount]
};
var pageVisit = new PageVisit
{
SessionId = sessionId,
VisitTime = session.StartTime
};
ravenSession.Store(session);
ravenSession.Store(pageVisit);
}
ravenSession.SaveChanges();
ravenSession.Dispose();
}
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace RavenTest
{
public class VisitSession
{
public string SessionId { get; set; }
public DateTime StartTime { get; set; }
public bool IsNewVisit { get; set; }
public string UniqueVisitorId { get; set; }
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace RavenTest.Index
{
public class VisitSummaryByDate
{
public DateTime Date { get; set; }
public int TotalVisitSessions { get; set; }
public int TotalNewVisitors { get; set; }
public int TotalUniqueVisitors { get; set; }
public int TotalPageVisits { get; set; }
internal string[] UniqueVisitorIds { get; set; }
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Raven.Client.Indexes;
namespace RavenTest.Index
{
public class VisitSummaryByDateIndex : AbstractMultiMapIndexCreationTask<VisitSummaryByDate>
{
public VisitSummaryByDateIndex()
{
AddMap<VisitSession>(sessions => from s in sessions
select new VisitSummaryByDate
{
Date = s.StartTime.Date,
TotalVisitSessions = 1,
TotalPageVisits = 0,
TotalNewVisitors = s.IsNewVisit ? 1 : 0,
TotalUniqueVisitors = 0,
UniqueVisitorIds = new [] { s.UniqueVisitorId }
});
AddMap<PageVisit>(visits => from v in visits
select new VisitSummaryByDate
{
Date = v.VisitTime.Date,
TotalVisitSessions = 0,
TotalPageVisits = 1,
TotalNewVisitors = 0,
TotalUniqueVisitors = 0,
UniqueVisitorIds = new string[0]
});
Reduce = results => from result in results
group result by result.Date into g
let uniqueVisitorIds = g.SelectMany(it => it.UniqueVisitorIds).Distinct().ToArray()
select new VisitSummaryByDate
{
Date = g.Key,
TotalVisitSessions = g.Sum(it => it.TotalVisitSessions),
TotalPageVisits = g.Sum(it => it.TotalPageVisits),
TotalNewVisitors = g.Sum(it => it.TotalNewVisitors),
TotalUniqueVisitors = uniqueVisitorIds.Length,
UniqueVisitorIds = uniqueVisitorIds
};
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment