Beispiel #1
0
        public async Task <NumbersTimelineStatsResult> GetNumbersTimelineStatsAsync(IEnumerable <FieldAggregation> fields, DateTime utcStart, DateTime utcEnd, string systemFilter, string userFilter = null, TimeSpan?displayTimeOffset = null, int desiredDataPoints = 100)
        {
            if (!displayTimeOffset.HasValue)
            {
                displayTimeOffset = TimeSpan.Zero;
            }

            var filter = new ElasticQuery()
                         .WithSystemFilter(systemFilter)
                         .WithFilter(userFilter)
                         .WithDateRange(utcStart, utcEnd, EventIndex.Fields.PersistentEvent.Date)
                         .WithIndices(utcStart, utcEnd, $"'{_eventIndex.VersionedName}-'yyyyMM");

            // if no start date then figure out first event date
            if (!filter.DateRanges.First().UseStartDate)
            {
                await UpdateFilterStartDateRangesAsync(filter, utcEnd).AnyContext();
            }

            utcStart = filter.DateRanges.First().GetStartDate();
            utcEnd   = filter.DateRanges.First().GetEndDate();
            var interval = GetInterval(utcStart, utcEnd, desiredDataPoints);

            var response = await _elasticClient.SearchAsync <PersistentEvent>(s => s
                                                                              .SearchType(SearchType.Count)
                                                                              .IgnoreUnavailable()
                                                                              .Index(filter.Indices.Count > 0 ? String.Join(",", filter.Indices) : _eventIndex.AliasName)
                                                                              .Query(_queryBuilder.BuildQuery <PersistentEvent>(filter))
                                                                              .Aggregations(agg => BuildAggregations(agg
                                                                                                                     .DateHistogram("timelime", t => t
                                                                                                                                    .Field(ev => ev.Date)
                                                                                                                                    .MinimumDocumentCount(0)
                                                                                                                                    .Interval(interval.Item1)
                                                                                                                                    .TimeZone(HoursAndMinutes(displayTimeOffset.Value))
                                                                                                                                    .Aggregations(agg2 => BuildAggregations(agg2, fields))
                                                                                                                                    )
                                                                                                                     .Min("first_occurrence", t => t.Field(ev => ev.Date))
                                                                                                                     .Max("last_occurrence", t => t.Field(ev => ev.Date)), fields)
                                                                                            )
                                                                              ).AnyContext();

            if (!response.IsValid)
            {
                _logger.Error("Retrieving stats failed: {0}", response.ServerError.Error);
                throw new ApplicationException("Retrieving stats failed.");
            }

            var stats = new NumbersTimelineStatsResult {
                Total = response.Total, Numbers = GetNumbers(response.Aggs, fields)
            };
            var timeline = response.Aggs.DateHistogram("timelime");

            if (timeline != null)
            {
                stats.Timeline.AddRange(timeline.Items.Select(i => new NumbersTimelineItem {
                    Date    = i.Date,
                    Total   = i.DocCount,
                    Numbers = GetNumbers(i, fields)
                }));
            }

            stats.Start = stats.Timeline.Count > 0 ? stats.Timeline.Min(tl => tl.Date).SafeAdd(displayTimeOffset.Value) : utcStart.SafeAdd(displayTimeOffset.Value);
            stats.End   = utcEnd.SafeAdd(displayTimeOffset.Value);

            var totalHours = stats.End.Subtract(stats.Start).TotalHours;

            if (totalHours > 0.0)
            {
                stats.AvgPerHour = stats.Total / totalHours;
            }

            if (stats.Timeline.Count <= 0)
            {
                return(stats);
            }

            var firstOccurrence = response.Aggs.Min("first_occurrence");

            if (firstOccurrence?.Value != null)
            {
                stats.FirstOccurrence = firstOccurrence.Value.Value.ToDateTime().SafeAdd(displayTimeOffset.Value);
            }

            var lastOccurrence = response.Aggs.Max("last_occurrence");

            if (lastOccurrence?.Value != null)
            {
                stats.LastOccurrence = lastOccurrence.Value.Value.ToDateTime().SafeAdd(displayTimeOffset.Value);
            }

            return(stats);
        }
Beispiel #2
0
        public async Task <NumbersTimelineStatsResult> GetNumbersTimelineStatsAsync(IEnumerable <FieldAggregation> fields, DateTime utcStart, DateTime utcEnd, IExceptionlessSystemFilterQuery systemFilter, string userFilter = null, TimeSpan?displayTimeOffset = null, int desiredDataPoints = 100)
        {
            if (!displayTimeOffset.HasValue)
            {
                displayTimeOffset = TimeSpan.Zero;
            }

            var filter = new ElasticQuery()
                         .WithSystemFilter(systemFilter)
                         .WithFilter(userFilter)
                         .WithDateRange(utcStart, utcEnd, EventIndexType.Fields.Date)
                         .WithIndexes(utcStart, utcEnd);

            // if no start date then figure out first event date
            if (!filter.DateRanges.First().UseStartDate)
            {
                await UpdateFilterStartDateRangesAsync(filter, utcEnd).AnyContext();
            }

            utcStart = filter.DateRanges.First().GetStartDate();
            utcEnd   = filter.DateRanges.First().GetEndDate();
            var interval = GetInterval(utcStart, utcEnd, desiredDataPoints);

            var descriptor = new SearchDescriptor <PersistentEvent>()
                             .SearchType(SearchType.Count)
                             .IgnoreUnavailable()
                             .Indices(_configuration.Events.Event.GetIndexesByQuery(filter))
                             .Type(_configuration.Events.Event.Name)
                             .Aggregations(agg => BuildAggregations(agg
                                                                    .DateHistogram("timelime", t => t
                                                                                   .Field(ev => ev.Date)
                                                                                   .MinimumDocumentCount(0)
                                                                                   .Interval(interval.Item1)
                                                                                   .TimeZone(HoursAndMinutes(displayTimeOffset.Value))
                                                                                   .Aggregations(agg2 => BuildAggregations(agg2, fields))
                                                                                   )
                                                                    .Min("first_occurrence", t => t.Field(ev => ev.Date))
                                                                    .Max("last_occurrence", t => t.Field(ev => ev.Date)), fields)
                                           );

            _configuration.Events.Event.QueryBuilder.ConfigureSearch(filter, GetQueryOptions(), descriptor);
            var response = await _configuration.Client.SearchAsync <PersistentEvent>(descriptor).AnyContext();

            _logger.Trace(() => response.GetRequest());

            if (!response.IsValid)
            {
                string message = $"Retrieving stats failed: {response.GetErrorMessage()}";
                _logger.Error().Exception(response.ConnectionStatus.OriginalException).Message(message).Property("request", response.GetRequest()).Write();
                throw new ApplicationException(message, response.ConnectionStatus.OriginalException);
            }

            var stats = new NumbersTimelineStatsResult {
                Total = response.Total, Numbers = GetNumbers(response.Aggs, fields)
            };
            var timeline = response.Aggs.DateHistogram("timelime");

            if (timeline != null)
            {
                stats.Timeline.AddRange(timeline.Items.Select(i => new NumbersTimelineItem {
                    Date    = i.Date,
                    Total   = i.DocCount,
                    Numbers = GetNumbers(i, fields)
                }));
            }

            stats.Start = stats.Timeline.Count > 0 ? stats.Timeline.Min(tl => tl.Date).SafeAdd(displayTimeOffset.Value) : utcStart.SafeAdd(displayTimeOffset.Value);
            stats.End   = utcEnd.SafeAdd(displayTimeOffset.Value);

            var totalHours = stats.End.Subtract(stats.Start).TotalHours;

            if (totalHours > 0.0)
            {
                stats.AvgPerHour = stats.Total / totalHours;
            }

            if (stats.Timeline.Count <= 0)
            {
                return(stats);
            }

            var firstOccurrence = response.Aggs.Min("first_occurrence");

            if (firstOccurrence?.Value != null)
            {
                stats.FirstOccurrence = firstOccurrence.Value.Value.ToDateTime().SafeAdd(displayTimeOffset.Value);
            }

            var lastOccurrence = response.Aggs.Max("last_occurrence");

            if (lastOccurrence?.Value != null)
            {
                stats.LastOccurrence = lastOccurrence.Value.Value.ToDateTime().SafeAdd(displayTimeOffset.Value);
            }

            return(stats);
        }