private int GetPeriodCount(DateTime start, DateTime end, SpanPeriod spanPeriod, int spanCount) { switch (spanPeriod) { case SpanPeriod.Day: case SpanPeriod.Week: var periodSpan = ToTimeSpan(spanPeriod, spanCount); return (int) Math.Ceiling((end - start).TotalHours / periodSpan.TotalHours); case SpanPeriod.Month: return MonthsSpanned(start, end); case SpanPeriod.Year: return YearsSpanned(start, end); } throw new Exception("Unhandled period: " + spanPeriod); }
public TimelineResult Timeline(string query, SpanPeriod spanPeriod, int spanCount) { var q = ToQuery(query); var results = new TimelineResult(); if (CountOfIndexedFiles > 0) { using (var wrapper = mainSearchManager.Wrapper()) { var hits = wrapper.IndexSearcher.search( q, null, CountOfIndexedFiles, new Sort(new SortField(FieldName.CreatedDate, SortField.Type.STRING, true))); var dateRangeMatches = hits.totalHits; if (dateRangeMatches > 0) { var docs = hits.scoreDocs; var newestDoc = wrapper.IndexSearcher.doc(docs[0].doc); var oldestDoc = wrapper.IndexSearcher.doc(docs[dateRangeMatches - 1].doc); results.OldestMatchingDate = oldestDoc.ToDateTime(FieldName.CreatedDate).Value; results.NewestMatchingDate = newestDoc.ToDateTime(FieldName.CreatedDate).Value; results.TotalMatches = dateRangeMatches; var periodCount = GetPeriodCount(results.OldestMatchingDate, results.NewestMatchingDate, spanPeriod, spanCount); // The documents are sorted newest date first, so the dates manipulation counts down int matchIndex = 0; results.Timeline = new List<TimelinePeriod>(periodCount); var currentEnd = GetEndDateTime(results.NewestMatchingDate, spanPeriod); for (int timelineIndex = 0; timelineIndex < periodCount; ++timelineIndex) { var currentStart = GetStartDateTime(currentEnd, spanPeriod, spanCount); var currentPeriod = new TimelinePeriod { Start = currentStart }; results.Timeline.Add(currentPeriod); while (matchIndex < dateRangeMatches) { var doc = wrapper.IndexSearcher.doc(docs[matchIndex].doc); var docDate = doc.ToDateTime(FieldName.CreatedDate).Value; if (docDate > currentStart) { ++currentPeriod.Count; ++matchIndex; } else { break; } } currentEnd = currentStart; } if (matchIndex != dateRangeMatches) logger.Warn("Missed some matches; should have placed {0}, but placed {1}", dateRangeMatches, matchIndex); } } } return results; }
private DateTime GetEndDateTime(DateTime endDateTime, SpanPeriod spanPeriod) { switch (spanPeriod) { case SpanPeriod.Day: case SpanPeriod.Week: return new DateTime(endDateTime.Year, endDateTime.Month, endDateTime.Day); case SpanPeriod.Month: return new DateTime(endDateTime.Year, endDateTime.Month, DateTime.DaysInMonth(endDateTime.Year, endDateTime.Month)); case SpanPeriod.Year: return new DateTime(endDateTime.Year, 12, 31); } throw new Exception("Unhandled period: " + spanPeriod); }
private DateTime GetStartDateTime(DateTime endDateTime, SpanPeriod spanPeriod, int count) { switch (spanPeriod) { case SpanPeriod.Day: case SpanPeriod.Week: return endDateTime - ToTimeSpan(spanPeriod, count); case SpanPeriod.Month: if (endDateTime.Day == 1) { if (endDateTime.Month == 1) return new DateTime(endDateTime.Year - 1, 12, 1); return new DateTime(endDateTime.Year, endDateTime.Month - 1, 1); } return new DateTime(endDateTime.Year, endDateTime.Month, 1); case SpanPeriod.Year: if (endDateTime.Month == 1 && endDateTime.Day == 1) return new DateTime(endDateTime.Year - 1, 1, 1); return new DateTime(endDateTime.Year, 1, 1); } throw new Exception("Unhandled period: " + spanPeriod); }
private TimeSpan ToTimeSpan(SpanPeriod spanPeriod, int count) { switch (spanPeriod) { case SpanPeriod.Day: return new TimeSpan(24 * count, 0, 0); case SpanPeriod.Week: return new TimeSpan(7 * count, 0, 0, 0); } throw new Exception("Unhandled period: " + spanPeriod); }