Esempio n. 1
0
        public async Task <NumbersTermStatsResult> GetNumbersTermsStatsAsync(string term, IEnumerable <FieldAggregation> fields, DateTime utcStart, DateTime utcEnd, string systemFilter, string userFilter = null, TimeSpan?displayTimeOffset = null, int max = 25)
        {
            var allowedTerms = new[] { "organization_id", "project_id", "stack_id", "tags", "version" };

            if (!allowedTerms.Contains(term))
            {
                throw new ArgumentException("Must be a valid term.", nameof(term));
            }

            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 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
                                                                                                                     .Terms("terms", t => BuildTermSort(t
                                                                                                                                                        .Field(term)
                                                                                                                                                        .Size(max)
                                                                                                                                                        .Aggregations(agg2 => BuildAggregations(agg2
                                                                                                                                                                                                .Min("first_occurrence", o => o.Field(ev => ev.Date))
                                                                                                                                                                                                .Max("last_occurrence", o => o.Field(ev => ev.Date)), fields)
                                                                                                                                                                      ), fields)
                                                                                                                            ), fields)
                                                                                            )
                                                                              ).AnyContext();

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

            var stats = new NumbersTermStatsResult {
                Total   = response.Total,
                Start   = utcStart.SafeAdd(displayTimeOffset.Value),
                End     = utcEnd.SafeAdd(displayTimeOffset.Value),
                Numbers = GetNumbers(response.Aggs, fields)
            };

            var terms = response.Aggs.Terms("terms");

            if (terms != null)
            {
                stats.Terms.AddRange(terms.Items.Select(i => {
                    var item = new NumbersTermStatsItem {
                        Total   = i.DocCount,
                        Term    = i.Key,
                        Numbers = GetNumbers(i, fields)
                    };

                    var termFirstOccurrence = i.Min("first_occurrence");
                    if (termFirstOccurrence?.Value != null)
                    {
                        item.FirstOccurrence = termFirstOccurrence.Value.Value.ToDateTime().SafeAdd(displayTimeOffset.Value);
                    }

                    var termLastOccurrence = i.Max("last_occurrence");
                    if (termLastOccurrence?.Value != null)
                    {
                        item.LastOccurrence = termLastOccurrence.Value.Value.ToDateTime().SafeAdd(displayTimeOffset.Value);
                    }

                    return(item);
                }));
            }

            return(stats);
        }
Esempio n. 2
0
        public async Task <NumbersTermStatsResult> GetNumbersTermsStatsAsync(string term, IEnumerable <FieldAggregation> fields, DateTime utcStart, DateTime utcEnd, IExceptionlessSystemFilterQuery systemFilter, string userFilter = null, TimeSpan?displayTimeOffset = null, int max = 25)
        {
            var allowedTerms = new[] { "organization_id", "project_id", "stack_id", "tags", "version" };

            if (!allowedTerms.Contains(term))
            {
                throw new ArgumentException("Must be a valid term.", nameof(term));
            }

            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 descriptor = new SearchDescriptor <PersistentEvent>()
                             .SearchType(SearchType.Count)
                             .IgnoreUnavailable()
                             .Indices(_configuration.Events.Event.GetIndexesByQuery(filter))
                             .Type(_configuration.Events.Event.Name)
                             .Aggregations(agg => BuildAggregations(agg
                                                                    .Terms("terms", t => BuildTermSort(t
                                                                                                       .Field(term)
                                                                                                       .Size(max)
                                                                                                       .Aggregations(agg2 => BuildAggregations(agg2
                                                                                                                                               .Min("first_occurrence", o => o.Field(ev => ev.Date))
                                                                                                                                               .Max("last_occurrence", o => o.Field(ev => ev.Date)), fields)
                                                                                                                     ), fields)
                                                                           ), 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 NumbersTermStatsResult {
                Total   = response.Total,
                Start   = utcStart.SafeAdd(displayTimeOffset.Value),
                End     = utcEnd.SafeAdd(displayTimeOffset.Value),
                Numbers = GetNumbers(response.Aggs, fields)
            };

            var terms = response.Aggs.Terms("terms");

            if (terms != null)
            {
                stats.Terms.AddRange(terms.Items.Select(i => {
                    var item = new NumbersTermStatsItem {
                        Total   = i.DocCount,
                        Term    = i.Key,
                        Numbers = GetNumbers(i, fields)
                    };

                    var termFirstOccurrence = i.Min("first_occurrence");
                    if (termFirstOccurrence?.Value != null)
                    {
                        item.FirstOccurrence = termFirstOccurrence.Value.Value.ToDateTime().SafeAdd(displayTimeOffset.Value);
                    }

                    var termLastOccurrence = i.Max("last_occurrence");
                    if (termLastOccurrence?.Value != null)
                    {
                        item.LastOccurrence = termLastOccurrence.Value.Value.ToDateTime().SafeAdd(displayTimeOffset.Value);
                    }

                    return(item);
                }));
            }

            return(stats);
        }