public async Task CanGetNumbersAsync() { // capture start date before generating data to make sure that our time range for stats includes all items var startDate = DateTime.UtcNow.SubtractDays(60); const int eventCount = 100; await RemoveDataAsync(); await CreateDataAsync(eventCount, false); var fields = FieldAggregationProcessor.Process("distinct:stack_id,term:is_first_occurrence:-F", false); Assert.True(fields.IsValid); Assert.Equal(2, fields.Aggregations.Count); var result = await _stats.GetNumbersTimelineStatsAsync(fields.Aggregations, startDate, DateTime.UtcNow, null, userFilter : $"project:{TestConstants.ProjectId}"); Assert.Equal(eventCount, result.Total); Assert.Equal(eventCount, result.Timeline.Sum(t => t.Total)); Assert.Equal(2, result.Numbers.Length); Assert.Equal(await _stackRepository.CountAsync(), result.Numbers[0]); Assert.Equal(await _stackRepository.CountAsync(), result.Timeline.Sum(t => t.Numbers[1])); var stacks = await _stackRepository.GetByOrganizationIdAsync(TestConstants.OrganizationId, new PagingOptions().WithLimit(100)); foreach (var stack in stacks.Documents) { var nsr = await _stats.GetNumbersStatsAsync(fields.Aggregations, startDate, DateTime.UtcNow, null, userFilter : "stack:" + stack.Id); Assert.Equal(stack.TotalOccurrences, nsr.Total); } }
public async Task <IHttpActionResult> GetTimelineAsync(string fields = null, string filter = null, string time = null, string offset = null) { var far = FieldAggregationProcessor.Process(fields); if (!far.IsValid) { return(BadRequest(far.Message)); } var pr = QueryProcessor.Process(filter); if (!pr.IsValid) { return(BadRequest(pr.Message)); } var organizations = await GetAssociatedActiveOrganizationsAsync(_organizationRepository); if (organizations.Count == 0) { return(Ok(NumbersTimelineStatsResult.Empty)); } var ti = GetTimeInfo(time, offset, organizations.GetRetentionUtcCutoff()); var sf = new ExceptionlessSystemFilterQuery(organizations) { UsesPremiumFeatures = far.UsesPremiumFeatures || pr.UsesPremiumFeatures, IsUserOrganizationsFilter = true }; NumbersTimelineStatsResult result; try { result = await _stats.GetNumbersTimelineStatsAsync(far.Aggregations, ti.UtcRange.Start, ti.UtcRange.End, ShouldApplySystemFilter(sf, filter)?sf : null, pr.ExpandedQuery, ti.Offset); } catch (ApplicationException ex) { _logger.Error().Exception(ex) .Message("An error has occurred. Please check your search filter.") .Property("Search Filter", new { SystemFilter = sf, UserFilter = filter, Time = time, Offset = offset }) .Tag("Search") .Identity(ExceptionlessUser.EmailAddress) .Property("User", ExceptionlessUser) .SetActionContext(ActionContext).Write(); return(BadRequest("An error has occurred. Please check your search filter.")); } return(Ok(result)); }
public async Task <IHttpActionResult> GetTimelineAsync(string fields = null, string filter = null, string time = null, string offset = null) { var far = FieldAggregationProcessor.Process(fields); if (!far.IsValid) { return(BadRequest(far.Message)); } var processResult = QueryProcessor.Process(filter); if (!processResult.IsValid) { return(BadRequest(processResult.Message)); } string systemFilter = await GetAssociatedOrganizationsFilterAsync(_organizationRepository, far.UsesPremiumFeatures || processResult.UsesPremiumFeatures, HasOrganizationOrProjectFilter(filter)); NumbersTimelineStatsResult result; try { var timeInfo = GetTimeInfo(time, offset); result = await _stats.GetNumbersTimelineStatsAsync(far.Aggregations, timeInfo.UtcRange.Start, timeInfo.UtcRange.End, systemFilter, processResult.ExpandedQuery, timeInfo.Offset); } catch (ApplicationException ex) { _logger.Error().Exception(ex).Property("Search Filter", new { SystemFilter = systemFilter, UserFilter = filter, Time = time, Offset = offset }).Tag("Search").Identity(ExceptionlessUser.EmailAddress).Property("User", ExceptionlessUser).SetActionContext(ActionContext).Write(); return(BadRequest("An error has occurred. Please check your search filter.")); } return(Ok(result)); }