/// <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); }
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)); }
/// <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()); }
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)); }
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); }
/// <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); }