Exemple #1
0
        /// <summary>
        /// Drains at most 'maxElements' documents from the AggregateDocumentQueryExecutionComponent.
        /// </summary>
        /// <param name="maxElements">This value is ignored, since the aggregates are aggregated for you.</param>
        /// <param name="token">The cancellation token.</param>
        /// <returns>The aggregate result after all the continuations have been followed.</returns>
        /// <remarks>
        /// Note that this functions follows all continuations meaning that it won't return until all continuations are drained.
        /// This means that if you have a long running query this function will take a very long time to return.
        /// </remarks>
        public override async Task <QueryResponse> DrainAsync(int maxElements, CancellationToken token)
        {
            // Note-2016-10-25-felixfan: Given what we support now, we should expect to return only 1 document.
            // Note-2019-07-11-brchon: We can return empty pages until all the documents are drained,
            // but then we will have to design a continuation token.

            double     requestCharge       = 0;
            long       responseLengthBytes = 0;
            List <Uri> replicaUris         = new List <Uri>();
            ClientSideRequestStatistics requestStatistics       = new ClientSideRequestStatistics();
            PartitionedQueryMetrics     partitionedQueryMetrics = new PartitionedQueryMetrics();
            ResourceType resourceType = ResourceType.Document;
            string       containerRid = null;

            while (!this.IsDone)
            {
                QueryResponse result = await base.DrainAsync(int.MaxValue, token);

                if (!result.IsSuccessStatusCode)
                {
                    return(result);
                }

                containerRid         = result.QueryHeaders.ContainerRid;
                resourceType         = result.QueryHeaders.ResourceType;
                requestCharge       += result.Headers.RequestCharge;
                responseLengthBytes += result.ResponseLengthBytes;
                // DEVNOTE: Add when query metrics is supported
                // partitionedQueryMetrics += new PartitionedQueryMetrics(results.QueryMetrics);
                if (result.RequestStatistics != null)
                {
                    replicaUris.AddRange(result.RequestStatistics.ContactedReplicas);
                }

                foreach (CosmosElement element in result.CosmosElements)
                {
                    RewrittenAggregateProjections rewrittenAggregateProjections = new RewrittenAggregateProjections(
                        this.isValueAggregateQuery,
                        element);
                    this.singleGroupAggregator.AddValues(rewrittenAggregateProjections.Payload);
                }
            }

            List <CosmosElement> finalResult       = new List <CosmosElement>();
            CosmosElement        aggregationResult = this.singleGroupAggregator.GetResult();

            if (aggregationResult != null)
            {
                finalResult.Add(aggregationResult);
            }

            // The replicaUris may have duplicates.
            requestStatistics.ContactedReplicas.AddRange(replicaUris);

            return(QueryResponse.CreateSuccess(
                       result: finalResult,
                       count: finalResult.Count,
                       responseLengthBytes: responseLengthBytes,
                       responseHeaders: new CosmosQueryResponseMessageHeaders(
                           continauationToken: null,
                           disallowContinuationTokenMessage: null,
                           resourceType: resourceType,
                           containerRid: containerRid)
            {
                RequestCharge = requestCharge
            },
                       queryMetrics: this.GetQueryMetrics()));
        }
Exemple #2
0
        /// <summary>
        /// Drains at most 'maxElements' documents from the AggregateDocumentQueryExecutionComponent.
        /// </summary>
        /// <param name="maxElements">This value is ignored, since the aggregates are aggregated for you.</param>
        /// <param name="token">The cancellation token.</param>
        /// <returns>The aggregate result after all the continuations have been followed.</returns>
        /// <remarks>
        /// Note that this functions follows all continuations meaning that it won't return until all continuations are drained.
        /// This means that if you have a long running query this function will take a very long time to return.
        /// </remarks>
        public override async Task <FeedResponse <CosmosElement> > DrainAsync(int maxElements, CancellationToken token)
        {
            // Note-2016-10-25-felixfan: Given what we support now, we should expect to return only 1 document.
            double     requestCharge       = 0;
            long       responseLengthBytes = 0;
            List <Uri> replicaUris         = new List <Uri>();
            ClientSideRequestStatistics requestStatistics       = new ClientSideRequestStatistics();
            PartitionedQueryMetrics     partitionedQueryMetrics = new PartitionedQueryMetrics();

            while (!this.IsDone)
            {
                FeedResponse <CosmosElement> result = await base.DrainAsync(int.MaxValue, token);

                requestCharge           += result.RequestCharge;
                responseLengthBytes     += result.ResponseLengthBytes;
                partitionedQueryMetrics += new PartitionedQueryMetrics(result.QueryMetrics);
                if (result.RequestStatistics != null)
                {
                    replicaUris.AddRange(result.RequestStatistics.ContactedReplicas);
                }

                foreach (CosmosElement item in result)
                {
                    if (!(item is CosmosArray comosArray))
                    {
                        throw new InvalidOperationException("Expected an array of aggregate results from the execution context.");
                    }

                    List <AggregateItem> aggregateItems = new List <AggregateItem>();
                    foreach (CosmosElement arrayItem in comosArray)
                    {
                        aggregateItems.Add(new AggregateItem(arrayItem));
                    }

                    Debug.Assert(
                        aggregateItems.Count == this.aggregators.Length,
                        $"Expected {this.aggregators.Length} values, but received {aggregateItems.Count}.");

                    for (int i = 0; i < this.aggregators.Length; ++i)
                    {
                        this.aggregators[i].Aggregate(aggregateItems[i].Item);
                    }
                }
            }

            List <CosmosElement> finalResult = this.BindAggregateResults(
                this.aggregators.Select(aggregator => aggregator.GetResult()));

            // The replicaUris may have duplicates.
            requestStatistics.ContactedReplicas.AddRange(replicaUris);

            return(new FeedResponse <CosmosElement>(
                       finalResult,
                       finalResult.Count,
                       new StringKeyValueCollection()
            {
                {
                    HttpConstants.HttpHeaders.RequestCharge,
                    requestCharge.ToString(CultureInfo.InvariantCulture)
                }
            },
                       useETagAsContinuation: false,
                       queryMetrics: partitionedQueryMetrics,
                       requestStats: requestStatistics,
                       disallowContinuationTokenMessage: null,
                       responseLengthBytes: responseLengthBytes));
        }
Exemple #3
0
        /// <summary>
        /// Drains at most 'maxElements' documents from the <see cref="AggregateDocumentQueryExecutionComponent"/> .
        /// </summary>
        /// <param name="maxElements">This value is ignored, since the aggregates are aggregated for you.</param>
        /// <param name="token">The cancellation token.</param>
        /// <returns>The aggregate result after all the continuations have been followed.</returns>
        /// <remarks>
        /// Note that this functions follows all continuations meaning that it won't return until all continuations are drained.
        /// This means that if you have a long running query this function will take a very long time to return.
        /// </remarks>
        public override async Task <QueryResponse> DrainAsync(int maxElements, CancellationToken token)
        {
            token.ThrowIfCancellationRequested();

            // Note-2016-10-25-felixfan: Given what we support now, we should expect to return only 1 document.
            double     requestCharge       = 0;
            long       responseLengthBytes = 0;
            List <Uri> replicaUris         = new List <Uri>();
            ClientSideRequestStatistics requestStatistics       = new ClientSideRequestStatistics();
            PartitionedQueryMetrics     partitionedQueryMetrics = new PartitionedQueryMetrics();

            while (!this.IsDone)
            {
                QueryResponse result = await base.DrainAsync(int.MaxValue, token);

                if (!result.IsSuccessStatusCode)
                {
                    return(result);
                }

                requestCharge       += result.Headers.RequestCharge;
                responseLengthBytes += result.ResponseLengthBytes;
                //partitionedQueryMetrics += new PartitionedQueryMetrics(result.QueryMetrics);
                if (result.RequestStatistics != null)
                {
                    replicaUris.AddRange(result.RequestStatistics.ContactedReplicas);
                }

                foreach (CosmosElement item in result.CosmosElements)
                {
                    if (!(item is CosmosArray comosArray))
                    {
                        throw new InvalidOperationException("Expected an array of aggregate results from the execution context.");
                    }

                    List <AggregateItem> aggregateItems = new List <AggregateItem>();
                    foreach (CosmosElement arrayItem in comosArray)
                    {
                        aggregateItems.Add(new AggregateItem(arrayItem));
                    }

                    Debug.Assert(
                        aggregateItems.Count == this.aggregators.Length,
                        $"Expected {this.aggregators.Length} values, but received {aggregateItems.Count}.");

                    for (int i = 0; i < this.aggregators.Length; ++i)
                    {
                        this.aggregators[i].Aggregate(aggregateItems[i].Item);
                    }
                }
            }

            List <CosmosElement> finalResult = this.BindAggregateResults(
                this.aggregators.Select(aggregator => aggregator.GetResult()));

            // The replicaUris may have duplicates.
            requestStatistics.ContactedReplicas.AddRange(replicaUris);

            return(QueryResponse.CreateSuccess(
                       result: finalResult,
                       count: finalResult.Count,
                       responseLengthBytes: responseLengthBytes,
                       responseHeaders: new CosmosQueryResponseMessageHeaders(continauationToken: null, disallowContinuationTokenMessage: null)
            {
                RequestCharge = requestCharge
            }));
        }