Ok, so you say your Logs actually have StartDateTime and EndDateTime,
and you are calculating the Hours. Be careful there - even in the
same timezone, you may have abiguity around daylight savings time
transitions. In general with .Net (not just Raven), you never want to
fully trust a duration calculated by the difference between two
DateTime values. You can, however, trust a duration calculated by the
difference between two DateTimeOffset values. So my first
recomendation would be to use DateTimeOffset in your Log items. You
say you are "presently" in a single time zone. If this were to ever
change, you would need to do that anyway. You can certainly still
take the duration ahead of time, before putting it in the Hours field
- or you could calculate this on the fly if you were to store both
start and end times. You may want to consider a decimal hours field
instead of integer - unless you are rounding to the nearest hour or
something.
You also need to consider what you want to do with Logs that cross
midnight. On the surface, you may just say that it all goes to the
start date. But what if it's an 10 hour duration and only 5 minutes
of it fell before midnight? Are you sure you want it all on the prior
day? Something to consider in your application design.
With regard to the plan dates, consider a plan that goes from Jan 1
2012 to Dec 31 2012. What value are you storing in the EndDate?
2012-12-31T00:00:00 or 2012-12-31T23:59:59 ? The latter will work,
but it's somewhat of a hack in that you have to manipulate the time
and be aware of the precision. The former will only work if you never
log time on Dec 31, or if you are translating your log time to
midnight with .Date - which is also a hack (IMHO). A better solution
is to use inclusive/exclusive ranges, basically store
2013-01-01T00:00:00 for the end date. A date is inside the range if
StartDate <= theDateInQuestion < EndDate. However, I must admit, I am
extremely opinionated in this area, and many people prefer the fully
inclusive 23:59:59 approach.
Now to your original question, what to do about indexing. You
identified that you need per-day granularity, so that helps. I would
approach this with a map/reduce index of logs, grouped by category and
calendar date (at midnight via .Date property), summing the duration
in the reduce. I also think you are missing a UserId of some type
here? You may want to include that in the Log and group by it as
well. If you are just getting the plan totals for a single plan, then
you can query directly into this index with the date range in question
for the categories in your plan (proably you need to
use .In(categories))
However, if you want a list of all plans including their totals, then
you should build a multi-map index. You'll map from Plan and Log
separately, and then join them together in the reduce, using similar
logic (date between date range, category in categories, etc.). This
may be more challenging to write, but it will avoid a SELECT N+1 issue
with just calling the other index for each plan.
Hope this sheds some light on the issues you will encounter. BTW - I
have very similar concerns in my core work application doing employee
time-and-attendance tracking. If I can be of any further help, please
ask.
-Matt
On Nov 23, 3:17 am, Chris Mcvittie <
bikk...@gmail.com> wrote:
> Replies inline.
>
> Thanks
>
> On Thursday, 22 November 2012 23:45:19 UTC, Oren Eini wrote:
>
> > In addition, is it possible to have a log against a category on a plan
> > _outside_ the Plan's dates?
>
> Yes - logs and plans are independent. Typically someone will have a 12
> month plan, and then another for the next year. They then just log to
> their journal on a daily/weekly basis.
>
>
>
> > On Thu, Nov 22, 2012 at 11:50 PM, Matt Johnson <
mj1...@hotmail.com<javascript:>