示例#1
0
        /// <summary>
        /// This will execute a DocumentDB query in the form of an IQueryable (Linq form) and return the results.
        ///
        /// It handles paging, continuation tokens, and retriable errors such as "too many requests" for you,
        /// while aggregating all query results in-memory before returning.
        /// </summary>
        /// <typeparam name="R"></typeparam>
        /// <param name="queryable"></param>
        /// <param name="queryExecutionHandler"></param>
        /// <param name="enumerationExceptionHandler"></param>
        /// <param name="feedResponseHandler"></param>
        /// <param name="maxRetries"></param>
        /// <param name="maxTime"></param>
        /// <param name="shouldRetry"></param>
        /// <returns></returns>
        public static async Task <IList <R> > ExecuteQueryWithContinuationAndRetry <R>(IQueryable <R> queryable, QueryExecutionHandler queryExecutionHandler, EnumerationExceptionHandler enumerationExceptionHandler, FeedResponseHandler feedResponseHandler, int maxRetries, TimeSpan maxTime, ShouldRetry shouldRetry)
        {
            IDocumentQuery <R> query = null;

            try
            {
                query = queryable.AsDocumentQuery();
            }
            catch (Exception e)
            {
                throw new ArgumentException(BadQueryableMessage, e);
            }

            var context = new FeedResponseContext();

            queryExecutionHandler(context, query.ToString());

            feedResponseHandler(context, FeedResponseType.BeforeEnumeration, null);

            var allResults = new List <R>();

            while (query.HasMoreResults)
            {
                FeedResponse <R> intermediateResponse = null;
                try
                {
                    intermediateResponse = await DocumentDbReliableExecution.ExecuteResultWithRetry(() =>
                                                                                                    query.ExecuteNextAsync <R>(),
                                                                                                    null,
                                                                                                    maxRetries,
                                                                                                    maxTime,
                                                                                                    shouldRetry);
                }
                catch (Exception ex)
                {
                    bool handled = enumerationExceptionHandler(context, ex);
                    if (!handled)
                    {
                        feedResponseHandler(context, FeedResponseType.EnumerationAborted, null);
                        throw;
                    }
                    else
                    {
                        break;
                    }
                }

                // lots of interesting info in intermediateResults such as RU usage, etc.
                List <R> intermediateResults = intermediateResponse.ToList();
                UpdateContext <R>(context, intermediateResponse, JsonConvert.SerializeObject(intermediateResults).Length, query.HasMoreResults);
                feedResponseHandler(context, FeedResponseType.PageReceived, new FeedResponseWrapper <R>(intermediateResponse));

                allResults.AddRange(intermediateResults);
            }

            feedResponseHandler(context, FeedResponseType.AfterEnumeration, null);

            return(allResults);
        }
示例#2
0
        public string Build()
        {
            var expressionObj = JObject.Parse(_query.ToString());
            var sql           = expressionObj["query"].Value <string>();

            var regex = new Regex(ArrayContainsRegEx);

            return(regex.Replace(sql, MatchEval));
        }
示例#3
0
        /// <summary>
        /// Executes the specified <see cref="IDocumentQuery{T}"/> asynchronously.
        /// </summary>
        /// <typeparam name="T">The result type.</typeparam>
        /// <param name="query">The query to execute.</param>
        /// <returns>The array of records returned by the query.</returns>
        protected async Task <T[]> ExecutedQueryAsync <T>(IDocumentQuery <T> query)
        {
            var    result        = new List <T>();
            double requestCharge = 0;

            while (query.HasMoreResults)
            {
                FeedResponse <T> queryResponse = await query.ExecuteNextAsync <T>();

                result.AddRange(queryResponse.ToArray());
                requestCharge += queryResponse.RequestCharge;
            }

            Log.LogInformation($"Query '{this.UnescapeQuotes(query.ToString())}', cost {requestCharge} RUs");
            return(result.ToArray());
        }
示例#4
0
        internal static async Task <DocumentsPage <R> > BeginPagingWithRetry <R>(IDocumentQuery <R> query, QueryExecutionHandler queryExecutionHandler, EnumerationExceptionHandler enumerationExceptionHandler, FeedResponseHandler feedResponseHandler, int maxRetries, TimeSpan maxTime, ShouldRetry shouldRetry)
        {
            var context = MakeFirstContextForPaging(query);

            queryExecutionHandler(context, query.ToString());

            feedResponseHandler(context, FeedResponseType.BeforeEnumeration, null);

            FeedResponse <R> firstPageResponse = null;

            while (firstPageResponse == null)
            {
                try
                {
                    firstPageResponse = await DocumentDbReliableExecution.ExecuteResultWithRetry(() =>
                                                                                                 query.ExecuteNextAsync <R>(),
                                                                                                 null,
                                                                                                 maxRetries,
                                                                                                 maxTime,
                                                                                                 shouldRetry);
                }
                catch (Exception ex)
                {
                    bool handled = enumerationExceptionHandler(context, ex);
                    if (!handled)
                    {
                        feedResponseHandler(context, FeedResponseType.EnumerationAborted, null);
                        throw;
                    }
                }
            }

            // lots of interesting info in intermediateResults such as RU usage, etc.
            List <R> firstPageResults = firstPageResponse.ToList();

            UpdateContext(context, firstPageResponse, JsonConvert.SerializeObject(firstPageResults).Length, query.HasMoreResults);
            feedResponseHandler(context, FeedResponseType.PageReceived, new FeedResponseWrapper <R>(firstPageResponse));

            if (!query.HasMoreResults)
            {
                DeletePagingContext(query);
            }

            return(new DocumentsPage <R>(firstPageResults, query.HasMoreResults ? firstPageResponse.ResponseContinuation : null));
        }
示例#5
0
        public async Task <IEnumerable <T> > GetItemsAsync(Expression <Func <T, bool> > predicate, string partitionKey = null)
        {
            var feedOptions = new FeedOptions {
                MaxItemCount = -1, PopulateQueryMetrics = true
            };

            if (string.IsNullOrEmpty(partitionKey))
            {
                feedOptions.EnableCrossPartitionQuery = true;
                System.Diagnostics.Debug.WriteLine("Executing Query without PartitionKey");
            }
            else
            {
                System.Diagnostics.Debug.WriteLine("Executing Query with PartitionKey");
                feedOptions.PartitionKey = new PartitionKey(partitionKey);
            }

            IDocumentQuery <T> query = _client.CreateDocumentQuery <T>(
                UriFactory.CreateDocumentCollectionUri(_cosmosContainerSettings.DatabaseId1, _cosmosContainerSettings.CollectionId), feedOptions)
                                       .Where(predicate)
                                       .AsDocumentQuery();


            System.Diagnostics.Debug.WriteLine($"Query: {query.ToString()}");

            List <T> results = new List <T>();

            while (query.HasMoreResults)
            {
                var response = await query.ExecuteNextAsync <T>();

                System.Diagnostics.Debug.WriteLine($"{response.RequestCharge}RU");
                System.Diagnostics.Debug.WriteLine("QueryMetrics:");
                System.Diagnostics.Debug.WriteLine(response.QueryMetrics.FirstOrDefault());
                results.AddRange(response);
            }

            return(results);
        }
        private static async Task <List <T> > GetResultsFromQueryToList <T>(IDocumentQuery <T> query, CancellationToken cancellationToken)
        {
            var results = new List <T>();

            while (query.HasMoreResults)
            {
                var items = await query.InvokeExecuteNextAsync(() => query.ExecuteNextAsync <T>(cancellationToken), query.ToString()).ExecuteCosmosCommand();

                results.AddRange(items);
            }
            return(results);
        }
示例#7
0
        /// <summary>
        /// This will execute a DocumentDB query in the form of an IQueryable (Linq form) and return the results.
        ///
        /// It handles paging, continuation tokens, and retriable errors such as "too many requests" for you,
        /// while streaming query results out in chunks via IEnumerable / yield.
        /// </summary>
        /// <typeparam name="R"></typeparam>
        /// <param name="queryable"></param>
        /// <param name="queryExecutionHandler"></param>
        /// <param name="enumerationExceptionHandler"></param>
        /// <param name="feedResponseHandler"></param>
        /// <param name="maxRetries"></param>
        /// <param name="maxTime"></param>
        /// <param name="shouldRetry"></param>
        /// <returns></returns>
        public static IEnumerable <R> StreamQueryWithContinuationAndRetry <R>(IQueryable <R> queryable, QueryExecutionHandler queryExecutionHandler, EnumerationExceptionHandler enumerationExceptionHandler, FeedResponseHandler feedResponseHandler, int maxRetries, TimeSpan maxTime, ShouldRetry shouldRetry)
        {
            IDocumentQuery <R> query = null;

            try
            {
                query = queryable.AsDocumentQuery();
            }
            catch (Exception e)
            {
                throw new ArgumentException(BadQueryableMessage, e);
            }

            var context = new FeedResponseContext();

            queryExecutionHandler(context, query.ToString());

            feedResponseHandler(context, FeedResponseType.BeforeEnumeration, null);

            while (query.HasMoreResults)
            {
                Task <FeedResponse <R> > t;
                try
                {
                    t = Task.Run(async() => await ExecuteResultWithRetry(() =>
                                                                         query.ExecuteNextAsync <R>(),
                                                                         null,
                                                                         maxRetries,
                                                                         maxTime,
                                                                         shouldRetry));

                    t.Wait();
                }
                catch (Exception ex)
                {
                    // note: if an IQueryable is returned to OData, throwing an exception here will cause it to take down w3wp.exe

                    bool handled = enumerationExceptionHandler(context, ex);
                    if (!handled)
                    {
                        feedResponseHandler(context, FeedResponseType.EnumerationAborted, null);
                        throw;
                    }
                    else
                    {
                        break;
                    }
                }

                var intermediateResponse = t.Result;

                // lots of interesting info in intermediateResults such as RU usage, etc.
                List <R> intermediateResults = intermediateResponse.ToList();
                UpdateContext <R>(context, intermediateResponse, JsonConvert.SerializeObject(intermediateResults).Length, query.HasMoreResults);
                feedResponseHandler(context, FeedResponseType.PageReceived, new FeedResponseWrapper <R>(intermediateResponse));

                foreach (var result in intermediateResults)
                {
                    yield return(result);
                }
            }

            feedResponseHandler(context, FeedResponseType.AfterEnumeration, null);
        }