public EventTermStatsResult GetTermsStats(DateTime utcStart, DateTime utcEnd, string term, string systemFilter, string userFilter = null, TimeSpan? displayTimeOffset = null, int max = 25, int desiredDataPoints = 10) { if (!displayTimeOffset.HasValue) displayTimeOffset = TimeSpan.Zero; var allowedTerms = new[] { "organization_id", "project_id", "stack_id", "tags", "version" }; if (!allowedTerms.Contains(term)) throw new ArgumentException("Must be a valid term.", "term"); var filter = new ElasticSearchOptions<PersistentEvent>() .WithFilter(!String.IsNullOrEmpty(systemFilter) ? Filter<PersistentEvent>.Query(q => q.QueryString(qs => qs.DefaultOperator(Operator.And).Query(systemFilter))) : null) .WithQuery(userFilter) .WithDateRange(utcStart, utcEnd, "date") .WithIndicesFromDateRange(); _client.EnableTrace(); // if no start date then figure out first event date if (!filter.UseStartDate) { var result = _client.Search<PersistentEvent>(s => s.IgnoreUnavailable().Index(filter.Indices.Count > 0 ? String.Join(",", filter.Indices) : String.Concat(ElasticSearchRepository<PersistentEvent>.EventsIndexName, "-*")).Filter(d => filter.GetElasticSearchFilter()).SortAscending(ev => ev.Date).Take(1)); var firstEvent = result.Hits.FirstOrDefault(); if (firstEvent != null) { utcStart = firstEvent.Source.Date.UtcDateTime; filter.WithDateRange(utcStart, utcEnd, "date"); filter.WithIndicesFromDateRange(); } } utcStart = filter.GetStartDate(); utcEnd = filter.GetEndDate(); var interval = GetInterval(utcStart, utcEnd, desiredDataPoints); var res = _client.Search<PersistentEvent>(s => s .SearchType(SearchType.Count) .IgnoreUnavailable() .Index(filter.Indices.Count > 0 ? String.Join(",", filter.Indices) : String.Concat(ElasticSearchRepository<PersistentEvent>.EventsIndexName, "-*")) .Aggregations(agg => agg .Filter("filtered", f => f .Filter(d => filter.GetElasticSearchFilter()) .Aggregations(filteredAgg => filteredAgg .Terms("terms", t => t .Field(term) .Size(max) .Aggregations(agg2 => agg2 .DateHistogram("timelime", tl => tl .Field(ev => ev.Date) .MinimumDocumentCount(0) .Interval(interval.Item1) .TimeZone(HoursAndMinutes(displayTimeOffset.Value)) ) .Cardinality("unique", u => u .Field(ev => ev.StackId) .PrecisionThreshold(1000) ) .Terms("new", u => u .Field(ev => ev.IsFirstOccurrence) .Exclude("F") ) .Min("first_occurrence", o => o.Field(ev => ev.Date)) .Max("last_occurrence", o => o.Field(ev => ev.Date)) ) ) ) ) ) ); if (!res.IsValid) { Log.Error().Message("Retrieving term stats failed: {0}", res.ServerError.Error).Write(); throw new ApplicationException("Retrieving term stats failed."); } _client.DisableTrace(); var filtered = res.Aggs.Filter("filtered"); if (filtered == null) return new EventTermStatsResult(); var stats = new EventTermStatsResult { Total = filtered.DocCount }; stats.Terms.AddRange(filtered.Terms("terms").Items.Select(i => { long count = 0; var timelineUnique = i.Cardinality("unique").Value; if (timelineUnique.HasValue) count = (long)timelineUnique.Value; var item = new TermStatsItem { Total = i.DocCount, Unique = count, Term = i.Key, New = i.Terms("new").Items.Count > 0 ? i.Terms("new").Items[0].DocCount : 0 }; var firstOccurrence = i.Min("first_occurrence").Value; var lastOccurrence = i.Max("last_occurrence").Value; if (firstOccurrence.HasValue) item.FirstOccurrence = firstOccurrence.Value.ToDateTime().SafeAdd(displayTimeOffset.Value); if (lastOccurrence.HasValue) item.LastOccurrence = lastOccurrence.Value.ToDateTime().SafeAdd(displayTimeOffset.Value); item.Timeline.AddRange(i.DateHistogram("timelime").Items.Select(ti => new TermTimelineItem { Date = ti.Date, Total = ti.DocCount })); return item; })); stats.Start = utcStart.SafeAdd(displayTimeOffset.Value); stats.End = utcEnd.SafeAdd(displayTimeOffset.Value); return stats; }
public EventTermStatsResult GetTermsStats(DateTime utcStart, DateTime utcEnd, string term, string query = null, TimeSpan? utcOffset = null, int max = 25, int desiredDataPoints = 10) { if (!utcOffset.HasValue) utcOffset = TimeSpan.Zero; var allowedTerms = new[] { "tags", "stack_id", "organization_id" }; if (!allowedTerms.Contains(term)) throw new ArgumentException("Must be a valid term.", "term"); var options = new ElasticSearchOptions<PersistentEvent>().WithQuery(query).WithDateRange(utcStart, utcEnd, "date").WithIndicesFromDateRange(); _client.EnableTrace(); var interval = GetInterval(utcStart, utcEnd, desiredDataPoints); var res = _client.Search<PersistentEvent>(s => s .SearchType(SearchType.Count) .IgnoreUnavailable() .Index(String.Join(",", options.Indices)) .Aggregations(agg => agg .Filter("filtered", f => f .Filter(d => options.GetElasticSearchFilter()) .Aggregations(filteredAgg => filteredAgg .Terms("terms", t => t .Field(term) .Size(max) .Aggregations(agg2 => agg2 .DateHistogram("timelime", tl => tl .Field(ev => ev.Date) .MinimumDocumentCount(0) .Interval(interval.Item1) .TimeZone(HoursAndMinutes(utcOffset.Value)) ) .Cardinality("unique", u => u .Field(ev => ev.StackId) .PrecisionThreshold(1000) ) .Terms("new", u => u .Field(ev => ev.IsFirstOccurrence) .Exclude("F") ) .Min("first_occurrence", o => o.Field(ev => ev.Date)) .Max("last_occurrence", o => o.Field(ev => ev.Date)) ) ) ) ) ) ); if (!res.IsValid) { Log.Error().Message("Retrieving term stats failed: {0}", res.ServerError.Error).Write(); throw new ApplicationException("Retrieving term stats failed."); } _client.DisableTrace(); var stats = new EventTermStatsResult { Total = res.Aggs.Filter("filtered").DocCount, }; stats.Terms.AddRange(res.Aggs.Filter("filtered").DateHistogram("terms").Items.Select(i => { long count = 0; var timelineUnique = i.Cardinality("unique").Value; if (timelineUnique.HasValue) count = (long)timelineUnique.Value; var item = new TermStatsItem { Total = i.DocCount, Unique = count, New = i.Terms("new").Items.Count > 0 ? i.Terms("new").Items[0].DocCount : 0 }; var firstOccurrence = i.Min("first_occurrence").Value; var lastOccurrence = i.Max("last_occurrence").Value; if (firstOccurrence.HasValue) item.FirstOccurrence = firstOccurrence.Value.ToDateTime(); if (lastOccurrence.HasValue) item.LastOccurrence = lastOccurrence.Value.ToDateTime(); item.Timeline.AddRange(i.DateHistogram("timelime").Items.Select(ti => new TermTimelineItem { Date = ti.Date, Total = ti.DocCount })); return item; })); stats.Start = utcStart.Add(utcOffset.Value); stats.End = utcEnd.Add(utcOffset.Value); return stats; }