Assuming your model looks something like this:
public class Calendar
{
public string Id {get; set;}
public DateTime Start {get; set;}
public int Duration {get; set;}
}
First you would define a type for the results you are wanting:
public class CalendarResult
{
public DateTime Date { get; set; }
public int Count { get; set; }
}
Then you can build a map-reduce index like this:
public class CalendarsByDate : AbstractIndexCreationTask<Calendar, CalendarResult>
{
public CalendarsByDate()
{
Map = calendars => from calendar in calendars
select new
{
calendar.Start.Date,
Count = 1
};
Reduce = results => from result in results
group result by result.Date
into g
select new
{
Date = g.Key,
Count = g.Sum(x => x.Count)
};
}
}
Add that to your database like this:
documentStore.ExecuteIndex(new CalendarsByDate());
Or if you have many indexes in your app, you may prefer to scan for them like this instead:
IndexCreation.CreateIndexes(GetType().Assembly, documentStore);
Then finally, you can query the index like this:
var results = session.Query<CalendarResult, CalendarsByDate>()
.Where(x => x.Date >= fromDate && x.Date <= toDate);
You can read more about map-reduce indexes here and here. There is a detailed explanation of how they work internally here.
One thing to note - I did not involve the duration of each item in this logic like you did in the original query. If you really think through what you're doing here, you'll find that you weren't really using that anyway. The only place it would matter is if your calendar events could span multiple days, in which case you've got a lot more work to do in either the EF or Raven form.