private async Task ExecuteReport() { QueryErrorMessage.Value = ""; IsErrorVisible.Value = false; if (string.IsNullOrEmpty(GroupByField.Value)) { ApplicationModel.Current.Notifications.Add(new Notification("You must select a field to group by")); return; } if (ValueCalculations.Count == 0) { ApplicationModel.Current.Notifications.Add(new Notification("You must add at least one Value")); return; } var facets = new List <AggregationQuery>(); foreach (var value in ValueCalculations) { var facetForField = facets.FirstOrDefault(f => f.AggregationField == value.Field); if (facetForField != null) { facetForField.Aggregation |= value.SummaryMode; } else { facets.Add(new AggregationQuery { Name = GroupByField.Value, DisplayName = GroupByField.Value + "-" + value.Field, AggregationField = value.Field, Aggregation = value.SummaryMode }); } } ResultColumns = null; Results.Clear(); var cancelationTokenSource = new CancellationTokenSource(); var progressWindow = new ProgressWindow() { Title = "Preparing Report", IsIndeterminate = false, CanCancel = true }; progressWindow.Closed += delegate { cancelationTokenSource.Cancel(); }; progressWindow.Show(); var queryStartTime = DateTime.UtcNow.Ticks; try { var results = new List <KeyValuePair <string, FacetResult> >(); var hasMoreResults = true; var fetchedResults = 0; while (hasMoreResults) { var queryFacetsTask = DatabaseCommands.GetFacetsAsync(IndexName, new IndexQuery() { Query = FilterDoc.Text }, AggregationQuery.GetFacets(facets), fetchedResults, 256); await TaskEx.WhenAny( queryFacetsTask, TaskEx.Delay(int.MaxValue, cancelationTokenSource.Token)); if (cancelationTokenSource.IsCancellationRequested) { return; } var facetResults = await queryFacetsTask; results.AddRange(facetResults.Results); fetchedResults += facetResults.Results.Select(r => r.Value.Values.Count).Max(); var remainingResults = facetResults.Results.Select(r => r.Value.RemainingTermsCount).Max(); var totalResults = fetchedResults + remainingResults; progressWindow.Progress = (int)((fetchedResults / (double)totalResults) * 100); hasMoreResults = remainingResults > 0; } var rowsByKey = new Dictionary <string, ReportRow>(); var rows = new List <ReportRow>(); foreach (var facetResult in results) { var calculatedField = facetResult.Key.Split('-')[1]; foreach (var facetValue in facetResult.Value.Values) { ReportRow result; if (!rowsByKey.TryGetValue(facetValue.Range, out result)) { result = new ReportRow { Key = facetValue.Range }; rowsByKey.Add(result.Key, result); rows.Add(result); } foreach ( var valueCalculation in ValueCalculations.Where(v => v.Field == calculatedField)) { var value = facetValue.GetAggregation(valueCalculation.SummaryMode); if (value.HasValue) { result.Values.Add(valueCalculation.Header, facetValue.GetAggregation(valueCalculation.SummaryMode) ?? 0); } } } } var columns = new ColumnsModel(); columns.Columns.Add(new ColumnDefinition() { Header = "Key", Binding = "Key" }); columns.Columns.AddRange( ValueCalculations.Select( k => new ColumnDefinition() { Header = k.Header, Binding = "Values[" + k.Header + "]" })); Results.AddRange(rows); ResultColumns = columns; var queryEndTime = DateTime.UtcNow.Ticks; ExecutionElapsedTime.Value = new TimeSpan(queryEndTime - queryStartTime); } catch (AggregateException ex) { var badRequest = ex.ExtractSingleInnerException() as BadRequestException; if (badRequest != null) { QueryErrorMessage.Value = badRequest.Message; IsErrorVisible.Value = true; } else { throw; } } catch (TaskCanceledException) { } finally { // there's a bug in silverlight where if a ChildWindow gets closed too soon after it's opened, it leaves the UI // disabled; so delay closing the window by a few milliseconds TaskEx.Delay(TimeSpan.FromMilliseconds(350)) .ContinueOnSuccessInTheUIThread(progressWindow.Close); } }
private async Task ExecuteReport() { QueryErrorMessage.Value = ""; IsErrorVisible.Value = false; if (string.IsNullOrEmpty(GroupByField.Value)) { ApplicationModel.Current.Notifications.Add(new Notification("You must select a field to group by")); return; } if (ValueCalculations.Count == 0) { ApplicationModel.Current.Notifications.Add(new Notification("You must add at least one Value")); return; } var facets = new List<AggregationQuery>(); foreach (var value in ValueCalculations) { var facetForField = facets.FirstOrDefault(f => f.AggregationField == value.Field); if (facetForField != null) { facetForField.Aggregation |= value.SummaryMode; } else { facets.Add(new AggregationQuery { Name = GroupByField.Value, DisplayName = GroupByField.Value + "-" + value.Field, AggregationField = value.Field, Aggregation = value.SummaryMode }); } } ResultColumns = null; Results.Clear(); var cancelationTokenSource = new CancellationTokenSource(); var progressWindow = new ProgressWindow() { Title = "Preparing Report", IsIndeterminate = false, CanCancel = true }; progressWindow.Closed += delegate { cancelationTokenSource.Cancel(); }; progressWindow.Show(); var queryStartTime = DateTime.UtcNow.Ticks; try { var results = new List<KeyValuePair<string, FacetResult>>(); var hasMoreResults = true; var fetchedResults = 0; while (hasMoreResults) { var queryFacetsTask = DatabaseCommands.GetFacetsAsync(IndexName, new IndexQuery() {Query = FilterDoc.Text}, AggregationQuery.GetFacets(facets), fetchedResults, 256); await TaskEx.WhenAny( queryFacetsTask, TaskEx.Delay(int.MaxValue, cancelationTokenSource.Token)); if (cancelationTokenSource.IsCancellationRequested) { return; } var facetResults = await queryFacetsTask; results.AddRange(facetResults.Results); fetchedResults += facetResults.Results.Select(r => r.Value.Values.Count).Max(); var remainingResults = facetResults.Results.Select(r => r.Value.RemainingTermsCount).Max(); var totalResults = fetchedResults + remainingResults; progressWindow.Progress = (int) ((fetchedResults/(double) totalResults)*100); hasMoreResults = remainingResults > 0; } var rowsByKey = new Dictionary<string, ReportRow>(); var rows = new List<ReportRow>(); foreach (var facetResult in results) { var calculatedField = facetResult.Key.Split('-')[1]; foreach (var facetValue in facetResult.Value.Values) { ReportRow result; if (!rowsByKey.TryGetValue(facetValue.Range, out result)) { result = new ReportRow {Key = facetValue.Range}; rowsByKey.Add(result.Key, result); rows.Add(result); } foreach ( var valueCalculation in ValueCalculations.Where(v => v.Field == calculatedField)) { var value = facetValue.GetAggregation(valueCalculation.SummaryMode); if (value.HasValue) { result.Values.Add(valueCalculation.Header, facetValue.GetAggregation(valueCalculation.SummaryMode) ?? 0); } } } } var columns = new ColumnsModel(); columns.Columns.Add(new ColumnDefinition() { Header = "Key", Binding = "Key" }); columns.Columns.AddRange( ValueCalculations.Select( k => new ColumnDefinition() {Header = k.Header, Binding = "Values[" + k.Header + "]"})); Results.AddRange(rows); ResultColumns = columns; var queryEndTime = DateTime.UtcNow.Ticks; ExecutionElapsedTime.Value = new TimeSpan(queryEndTime - queryStartTime); } catch (AggregateException ex) { var badRequest = ex.ExtractSingleInnerException() as BadRequestException; if (badRequest != null) { QueryErrorMessage.Value = badRequest.Message; IsErrorVisible.Value = true; } else { throw; } } catch (TaskCanceledException) { } finally { // there's a bug in silverlight where if a ChildWindow gets closed too soon after it's opened, it leaves the UI // disabled; so delay closing the window by a few milliseconds TaskEx.Delay(TimeSpan.FromMilliseconds(350)) .ContinueOnSuccessInTheUIThread(progressWindow.Close); } }