private readonly IDocumentTypeRepository _documentTypeRepository; //文档类型仓储 #endregion Fields #region Constructors public DocumentAppService(IDocumentQuery documentQuery, IDocumentRepository documentRepository, IDocumentTypeRepository documentTypeRepository) { _documentQuery = documentQuery; _documentRepository = documentRepository; _documentTypeRepository = documentTypeRepository; }
public AttachmentService(IGenericRepository<Attachment> attachmentRepository, IDocumentQuery<Attachment> documentQuery, IBlobRepository<Attachment> blobRepository) { _attachmentRepository = attachmentRepository; _documentQuery = documentQuery; _blobRepository = blobRepository; }
IEnumerator <TimeSeriesStreamResult <TimeSeriesRawResult <T> > > ITimeSeriesSessionStreamRawResultOperations.Stream <T>(IDocumentQuery <TimeSeriesRawResult <T> > query, out StreamQueryStatistics streamQueryStats) { return(StreamTimeSeriesInternal(query, out streamQueryStats)); }
public async Task <ActionResult> Query(string query, string locationName) { var newModel = new QueryModel { Documents = new List <string>(), Query = query }; var numRetries = 0; IDocumentQuery <dynamic> docQuery = null; if (docQuery != null) { do { try { var sw = Stopwatch.StartNew(); var results = await docQuery.ExecuteNextAsync(); sw.Stop(); newModel.ResponseTime = sw.ElapsedMilliseconds; foreach (var result in results) { string json = result.ToString(); var formattedJson = json.StartsWith("{", StringComparison.InvariantCulture) || json.StartsWith("[", StringComparison.InvariantCulture) ? JsonConvert.SerializeObject(JsonConvert.DeserializeObject(json), Formatting.Indented) : json; newModel.Documents.Add(formattedJson); newModel.Count++; } newModel.Error = null; newModel.StatusCode = 200; break; } catch (Exception e) { newModel.Documents.Clear(); numRetries++; var exception = e.InnerException as DocumentClientException; if (exception != null) { if (exception.StatusCode != null && (int)exception.StatusCode == 429) { numRetries--; } var startIndex = exception.Message.IndexOf("{", StringComparison.InvariantCulture); var endIndex = exception.Message.LastIndexOf("}", StringComparison.InvariantCulture) + 1; newModel.Error = startIndex < 0 || endIndex < 0 ? exception.Message : exception.Message.Substring(startIndex, endIndex - startIndex); if (exception.StatusCode != null) { newModel.StatusCode = (int)exception.StatusCode; } } else { newModel.Error = e.Message.Substring(0, e.Message.IndexOf(Environment.NewLine, StringComparison.OrdinalIgnoreCase)); } } } while (numRetries < 1); } Response.Write(JsonConvert.SerializeObject(newModel)); return(null); }
public IEnumerator <StreamResult <T> > Stream <T>(IDocumentQuery <T> query) { QueryHeaderInformation _; return(Stream <T>(query, out _)); }
private IEnumerator <TimeSeriesStreamResult <T> > StreamTimeSeriesInternal <T>(IDocumentQuery <T> query) where T : ITimeSeriesQueryStreamResult, new() { var streamOperation = new StreamOperation(this); var command = streamOperation.CreateRequest(query.GetIndexQuery()); RequestExecutor.Execute(command, Context, sessionInfo: _sessionInfo); streamOperation.EnsureIsAcceptable(query.IndexName, command.Result); var result = streamOperation.SetResultForTimeSeries(command.Result); return(YieldTimeSeriesResults(query, result)); }
public static IDocumentQuery <TS> Projection <T, TS>(this IDocumentQuery <T> query) { return(query.SelectFields <TS>(typeof(TS).GetProperties().Select(x => x.Name).ToArray())); }
public static async Task <T> FirstOrDefault <T>(this IDocumentQuery <T> query) { var response = await query.ExecuteNextAsync <T>().ConfigureAwait(false); return(response.Count >= 1 ? response.First() : default(T)); }
/// <inheritdoc/> public async Task <InstanceQueryResponse> GetInstancesOfApplication( Dictionary <string, StringValues> queryParams, string continuationToken, int size) { InstanceQueryResponse queryResponse = new InstanceQueryResponse(); FeedOptions feedOptions = new FeedOptions { EnableCrossPartitionQuery = true, MaxItemCount = size, }; if (continuationToken != null) { feedOptions.RequestContinuation = continuationToken; } IQueryable <Instance> queryBuilder = _client.CreateDocumentQuery <Instance>(_collectionUri, feedOptions); try { queryBuilder = BuildQueryFromParameters(queryParams, queryBuilder); } catch (Exception e) { queryResponse.Exception = e.Message; return(queryResponse); } try { IDocumentQuery <Instance> documentQuery = queryBuilder.AsDocumentQuery(); FeedResponse <Instance> feedResponse = await documentQuery.ExecuteNextAsync <Instance>(); if (!feedResponse.Any()) { queryResponse.Count = 0; queryResponse.TotalHits = 0; return(queryResponse); } string nextContinuationToken = feedResponse.ResponseContinuation; logger.LogInformation($"continuation token: {nextContinuationToken}"); // this migth be expensive feedOptions.RequestContinuation = null; int totalHits = queryBuilder.Count(); queryResponse.TotalHits = totalHits; List <Instance> instances = feedResponse.ToList <Instance>(); PostProcess(instances); queryResponse.Instances = instances; queryResponse.ContinuationToken = nextContinuationToken; queryResponse.Count = instances.Count; } catch (Exception e) { logger.LogError("error: {e}"); queryResponse.Exception = e.Message; } return(queryResponse); }
async Task IPartitionObserver <DocumentServiceLease> .OnPartitionAcquiredAsync(DocumentServiceLease lease) { Debug.Assert(lease != null && !string.IsNullOrEmpty(lease.Owner), "lease"); TraceLog.Informational(string.Format("Host '{0}' partition {1}: acquired!", this.HostName, lease.PartitionId)); #if DEBUG Interlocked.Increment(ref this.partitionCount); #endif IChangeFeedObserver observer = this.observerFactory.CreateObserver(); ChangeFeedObserverContext context = new ChangeFeedObserverContext { PartitionKeyRangeId = lease.PartitionId }; CancellationTokenSource cancellation = new CancellationTokenSource(); // Create ChangeFeedOptions to use for this worker. ChangeFeedOptions options = new ChangeFeedOptions { MaxItemCount = this.changeFeedOptions.MaxItemCount, PartitionKeyRangeId = this.changeFeedOptions.PartitionKeyRangeId, SessionToken = this.changeFeedOptions.SessionToken, StartFromBeginning = this.changeFeedOptions.StartFromBeginning, RequestContinuation = this.changeFeedOptions.RequestContinuation }; var workerTask = await Task.Factory.StartNew(async() => { ChangeFeedObserverCloseReason?closeReason = null; try { try { await observer.OpenAsync(context); } catch (Exception ex) { TraceLog.Error(string.Format("IChangeFeedObserver.OpenAsync exception: {0}", ex)); closeReason = ChangeFeedObserverCloseReason.ObserverError; throw; } options.PartitionKeyRangeId = lease.PartitionId; if (!string.IsNullOrEmpty(lease.ContinuationToken)) { options.RequestContinuation = lease.ContinuationToken; } IDocumentQuery <Document> query = this.documentClient.CreateDocumentChangeFeedQuery(this.collectionSelfLink, options); TraceLog.Verbose(string.Format("Worker start: partition '{0}', continuation '{1}'", lease.PartitionId, lease.ContinuationToken)); try { while (this.isShutdown == 0) { do { DocumentClientException dcex = null; FeedResponse <Document> response = null; try { response = await query.ExecuteNextAsync <Document>(); } catch (DocumentClientException ex) { if (StatusCode.NotFound != (StatusCode)ex.StatusCode && StatusCode.TooManyRequests != (StatusCode)ex.StatusCode && StatusCode.ServiceUnavailable != (StatusCode)ex.StatusCode) { throw; } dcex = ex; } if (dcex != null) { const int ReadSessionNotAvailable = 1002; if (StatusCode.NotFound == (StatusCode)dcex.StatusCode && GetSubStatusCode(dcex) != ReadSessionNotAvailable) { // Most likely, the database or collection was removed while we were enumerating. // Shut down. The user will need to start over. // Note: this has to be a new task, can't await for shutdown here, as shudown awaits for all worker tasks. await Task.Factory.StartNew(() => this.StopAsync(ChangeFeedObserverCloseReason.ResourceGone)); break; } else { Debug.Assert(StatusCode.TooManyRequests == (StatusCode)dcex.StatusCode || StatusCode.ServiceUnavailable == (StatusCode)dcex.StatusCode); TraceLog.Warning(string.Format("Partition {0}: retriable exception : {1}", context.PartitionKeyRangeId, dcex.Message)); await Task.Delay(dcex.RetryAfter != TimeSpan.Zero ? dcex.RetryAfter : this.options.FeedPollDelay, cancellation.Token); } } if (response != null) { if (response.Count > 0) { List <Document> docs = new List <Document>(); docs.AddRange(response); try { await observer.ProcessChangesAsync(context, docs); } catch (Exception ex) { TraceLog.Error(string.Format("IChangeFeedObserver.ProcessChangesAsync exception: {0}", ex)); closeReason = ChangeFeedObserverCloseReason.ObserverError; throw; } // Checkpoint after every successful delivery to the client. lease = await CheckpointAsync(lease, response.ResponseContinuation, context); } else if (string.IsNullOrEmpty(lease.ContinuationToken)) { // Checkpoint if we've never done that for this lease. lease = await CheckpointAsync(lease, response.ResponseContinuation, context); } } }while (query.HasMoreResults && this.isShutdown == 0); if (this.isShutdown == 0) { await Task.Delay(this.options.FeedPollDelay, cancellation.Token); } } // Outer while (this.isShutdown == 0) loop. } catch (TaskCanceledException) { Debug.Assert(cancellation.IsCancellationRequested, "cancellation.IsCancellationRequested"); TraceLog.Informational(string.Format("Cancel signal received for partition {0} worker!", context.PartitionKeyRangeId)); } } catch (LeaseLostException) { closeReason = ChangeFeedObserverCloseReason.LeaseLost; } catch (Exception ex) { TraceLog.Error(string.Format("Partition {0} exception: {1}", context.PartitionKeyRangeId, ex)); if (!closeReason.HasValue) { closeReason = ChangeFeedObserverCloseReason.Unknown; } } if (closeReason.HasValue) { TraceLog.Informational(string.Format("Releasing lease for partition {0} due to an error, reason: {1}!", context.PartitionKeyRangeId, closeReason.Value)); // Note: this has to be a new task, because OnPartitionReleasedAsync awaits for worker task. await Task.Factory.StartNew(async() => await this.partitionManager.TryReleasePartitionAsync(context.PartitionKeyRangeId, true, closeReason.Value)); } TraceLog.Informational(string.Format("Partition {0}: worker finished!", context.PartitionKeyRangeId)); }); var newWorkerData = new WorkerData(workerTask, observer, context, cancellation); this.partitionKeyRangeIdToWorkerMap.AddOrUpdate(context.PartitionKeyRangeId, newWorkerData, (string id, WorkerData d) => { return(newWorkerData); }); }
public static async System.Threading.Tasks.Task <IActionResult> RunAsync( [HttpTrigger(AuthorizationLevel.Function, "get", Route = "vip/{id}")] HttpRequestMessage req, [CosmosDB( databaseName: "contesthub", collectionName: "VIP", ConnectionStringSetting = "contesthub_DOCUMENTDB" )] DocumentClient client, string id, TraceWriter log) { //var jwtHandler = new JwtSecurityTokenHandler(); //var jwtInput = req.Headers.Authorization.ToString(); //var jwt = ""; //if (jwtInput.Contains("Bearer")) // jwt = jwtInput.Substring(7); //else // jwt = jwtInput; //var readableToken = jwtHandler.CanReadToken(jwt); //var dId = ""; //if (readableToken != true) //{ // return new NotFoundResult(); //} //if (readableToken == true) //{ // var token = jwtHandler.ReadJwtToken(jwt); // var claims = token.Claims; // var claim = claims.Where(c => c.Type == "upn").FirstOrDefault(); // dId = claim.Value.Substring(0, claim.Value.IndexOf('@')); //} //if(dId.ToLower()!=id.ToLower()) //{ // return new UnauthorizedResult(); //} log.Info($"Processed request for {id} in VIP"); Uri collectionUri = UriFactory.CreateDocumentCollectionUri("contesthub", "VIP"); Uri c2 = UriFactory.CreateDocumentCollectionUri("contesthub", "ProductionCalendar"); IDocumentQuery <ProductionCalendar> dateQuery = client.CreateDocumentQuery <ProductionCalendar>(c2, new FeedOptions { EnableCrossPartitionQuery = true }).AsDocumentQuery(); var dates = await dateQuery.ExecuteNextAsync <ProductionCalendar>(); var year = dates.FirstOrDefault().closedProdYear; var query = client.CreateDocumentQuery <VIPElement>(collectionUri, new FeedOptions { EnableCrossPartitionQuery = true, MaxItemCount = Int32.MaxValue }). Where(d => d.logonid.ToUpper() == id.ToUpper()); List <VIPElement> vipElementList = query.ToList(); vipElementList = vipElementList.Where(e => e.weekAndYear.Substring(e.weekAndYear.Length - 4, 4) == year).ToList(); if (vipElementList.Count == 0) { return(new NoContentResult()); } else { VIPResponseCurrent vipResponse = new VIPResponseCurrent(vipElementList); return(new OkObjectResult(vipResponse)); } }
private static async Task <FeedResponse <dynamic> > QuerySingleDocumentAsync(IDocumentQuery <dynamic> query) { return(await query.ExecuteNextAsync <dynamic>()); }
async void QueryDocumentCollectionsAsync(object resource, RequestOptions requestOptions) { try { var queryText = resource as string; // text is the querytext. IDocumentQuery <dynamic> q = null; var feedOptions = Program.GetMain().GetFeedOptions(); if (requestOptions == null) { // requestOptions = null means it is from the next page. We only attempt to continue using the RequestContinuation for next page button if (!string.IsNullOrEmpty(_currentContinuation) && string.IsNullOrEmpty(feedOptions.RequestContinuation)) { feedOptions.RequestContinuation = _currentContinuation; } } q = _client.CreateDocumentCollectionQuery((Tag as Database).GetLink(_client), queryText, feedOptions).AsDocumentQuery(); var sw = Stopwatch.StartNew(); FeedResponse <dynamic> r; using (PerfStatus.Start("QueryDocument")) { r = await q.ExecuteNextAsync(); } sw.Stop(); _currentContinuation = r.ResponseContinuation; _currentQueryCommandContext.HasContinuation = !string.IsNullOrEmpty(_currentContinuation); _currentQueryCommandContext.QueryStarted = true; // set the result window string text = null; if (r.Count > 1) { text = string.Format(CultureInfo.InvariantCulture, "Returned {0} collections in {1} ms.", r.Count, sw.ElapsedMilliseconds); } else { text = string.Format(CultureInfo.InvariantCulture, "Returned {0} collections in {1} ms.", r.Count, sw.ElapsedMilliseconds); } if (r.ResponseContinuation != null) { text += " (more results might be available)"; } var jsonarray = "["; var index = 0; foreach (var d in r) { index++; // currently Query.ToString() has Formatting.Indented, but the public release doesn't have yet. jsonarray += d.ToString(); if (index == r.Count) { jsonarray += "]"; } else { jsonarray += ",\r\n"; } } Program.GetMain().SetResultInBrowser(jsonarray, text, true, r.ResponseHeaders); Program.GetMain().SetNextPageVisibility(_currentQueryCommandContext); } catch (AggregateException e) { Program.GetMain().SetResultInBrowser(null, e.InnerException.ToString(), true); } catch (Exception e) { Program.GetMain().SetResultInBrowser(null, e.ToString(), true); } }
internal static void ValidateQuery <T>(DocumentClient client, string collectionLink, string queryProperty, string queryPropertyValue, int expectedCount, INameValueCollection headers = null) where T : CosmosResource, new() { if (headers != null) { headers = new StringKeyValueCollection(headers); // dont mess with the input headers } else { headers = new StringKeyValueCollection(); } int maxTries = 5; const int minIndexInterval = 5000; // 5 seconds while (maxTries-- > 0) { FeedResponse <dynamic> resourceFeed = null; IDocumentQuery <dynamic> queryService = null; string queryString = @"select * from root r where r." + queryProperty + @"=""" + queryPropertyValue + @""""; if (typeof(T) == typeof(CosmosDatabaseSettings)) { queryService = client.CreateDatabaseQuery(queryString).AsDocumentQuery(); } else if (typeof(T) == typeof(CosmosContainerSettings)) { queryService = client.CreateDocumentCollectionQuery(collectionLink, queryString).AsDocumentQuery(); } else if (typeof(T) == typeof(Document)) { queryService = client.CreateDocumentQuery(collectionLink, queryString).AsDocumentQuery(); } else { Assert.Fail("Unexpected type"); } while (queryService.HasMoreResults) { resourceFeed = queryService.ExecuteNextAsync().Result; if (resourceFeed.Count > 0) { Assert.IsNotNull(resourceFeed, "Query result is null"); Assert.AreNotEqual(0, resourceFeed.Count, "Query result is invalid"); foreach (T resource in resourceFeed) { if (queryProperty.Equals("name", StringComparison.CurrentCultureIgnoreCase)) { Assert.AreEqual(resource.Id, queryPropertyValue, "Result contain invalid result"); } } return; } } Task.Delay(minIndexInterval); } Assert.Fail("Query did not return result after max tries"); }
public AsyncEnumerator(IDocumentQuery <T> documentQuery) : base(documentQuery) { }
static async Task <List <Permission> > GetReadPermission(string userId, DocumentClient client, string databaseId, string collectionId) { List <Permission> movieReviewPermissions = new List <Permission>(); Uri collectionUri = UriFactory.CreateDocumentCollectionUri(databaseId, collectionId); Uri userUri = UriFactory.CreateUserUri(databaseId, userId); IDocumentQuery <MovieReview> query = null; // Get the public or public + premium docs (depending on the user we're working with) if (userId == publicUserId) { query = client.CreateDocumentQuery <MovieReview>(collectionUri).Where(mv => mv.IsPremium == false).AsDocumentQuery(); } else { query = client.CreateDocumentQuery <MovieReview>(collectionUri).AsDocumentQuery(); } // Now loop through the results and create individual permissions for them while (query.HasMoreResults) { foreach (var movieReview in await query.ExecuteNextAsync <MovieReview>()) { Permission individualPermission = new Permission(); string permissionId = $"{userId}-{movieReview.Id}"; try { // the permission ID's format: {userID}-{documentID} Uri permissionUri = UriFactory.CreatePermissionUri(databaseId, userId, permissionId); individualPermission = await client.ReadPermissionAsync(permissionUri); movieReviewPermissions.Add(individualPermission); } catch (DocumentClientException ex) { if (ex.StatusCode == HttpStatusCode.NotFound) { // The permission was not found - either the user (and permission) doesn't exist or permission doesn't exist await CreateUserIfNotExistAsync(userId, client, databaseId); var newPermission = new Permission { PermissionMode = PermissionMode.Read, Id = permissionId, ResourceLink = UriFactory.CreateDocumentUri(databaseId, collectionId, movieReview.Id).ToString() }; individualPermission = await client.CreatePermissionAsync(userUri, newPermission); movieReviewPermissions.Add(individualPermission); } else { throw ex; } } } } return(movieReviewPermissions); }
/// <summary> /// Query the facets results for this query using the specified facet document with the given start and pageSize /// </summary> /// <param name="facetSetupDoc">Name of the FacetSetup document</param> /// <param name="start">Start index for paging</param> /// <param name="pageSize">Paging PageSize. If set, overrides Facet.MaxResults</param> public static FacetResults ToFacets <T>(this IDocumentQuery <T> query, string facetSetupDoc, int start = 0, int?pageSize = null) { var documentQuery = ((DocumentQuery <T>)query); return(documentQuery.GetFacets(facetSetupDoc, start, pageSize)); }
/// <summary> /// Execute the function with retries on throttle /// </summary> internal static async Task <FeedResponse <T> > ExecuteNextWithRetriesAsync <T>(this IDocumentQuery <T> query, CancellationToken cancellationToken = default) { while (true) { TimeSpan timeSpan; try { return(await query.ExecuteNextAsync <T>(cancellationToken)); } catch (DocumentClientException ex) when(ex.StatusCode != null && (int)ex.StatusCode == 429) { timeSpan = ex.RetryAfter; } catch (AggregateException ex) when(ex.InnerException is DocumentClientException de && de.StatusCode != null && (int)de.StatusCode == 429) { timeSpan = de.RetryAfter; } await Task.Delay(timeSpan, cancellationToken); } }
internal virtual async Task <int> QueryAndVerifyDocuments(DocumentClient client, string collectionLink, IEnumerable <Query> queries, int pageSize = 1000, int retries = 0, bool allowScan = false) { // First we make sure that all the queries are inserted { List <dynamic> queriedDocuments = new List <dynamic>(); IDocumentQuery <Document> selectAllQuery = client.CreateDocumentQuery(collectionLink, feedOptions: new FeedOptions { MaxItemCount = pageSize, EnableScanInQuery = allowScan, EnableCrossPartitionQuery = true }).AsDocumentQuery(); while (selectAllQuery.HasMoreResults) { DocumentFeedResponse <dynamic> queryResultsPage = await selectAllQuery.ExecuteNextAsync(); System.Diagnostics.Trace.TraceInformation("ReadFeed continuation token: {0}, SessionToken: {1}", queryResultsPage.ResponseContinuation, queryResultsPage.SessionToken); queriedDocuments.AddRange(queryResultsPage); } List <dynamic> expected = new List <dynamic>(documents.Count()); for (int i = 0; i < documents.Count(); ++i) { expected.Add(JsonConvert.DeserializeObject(String.Format(CultureInfo.InvariantCulture, DocumentFormat, i + 1, String.Empty))); } queriedDocuments.Sort((doc1, doc2) => int.Parse(doc1.id).CompareTo(int.Parse(doc2.id))); var expectedIds = expected.Select(doc => doc.id.ToString()); var actualIds = queriedDocuments.Select(doc => doc.id.ToString()); if (!expectedIds.SequenceEqual(actualIds)) { System.Diagnostics.Trace.TraceInformation("Failed to insert all the documents, queried documents are:" + Environment.NewLine + String.Join(Environment.NewLine, queriedDocuments)); return(-1); } System.Diagnostics.Trace.TraceInformation("All the documents are inserted"); } // Query and verify TimeSpan totalQueryLatencyAllPages = TimeSpan.FromSeconds(0); uint numberOfQueries = 0; var failedQueries = new List <Query>(); List <Query> query_list = queries as List <Query> ?? queries.ToList(); foreach (var query in query_list) { var queriedDocuments = new List <string>(); List <string> activityIDsAllQueryPages = new List <string>(); if (numberOfQueries > 0 && numberOfQueries % 100 == 0) { System.Diagnostics.Trace.TraceInformation(DateTime.Now.ToString("HH:mm:ss.ffff") + @": Executing query {0} of {1}", (numberOfQueries + 1), query_list.Count()); System.Diagnostics.Trace.TraceInformation(@" Query latency per query (avg ms) {0} after {1} queries", totalQueryLatencyAllPages.TotalMilliseconds / numberOfQueries, numberOfQueries); } IDocumentQuery <dynamic> docQuery = client.CreateDocumentQuery(collectionLink, query.ToString(), feedOptions: new FeedOptions { MaxItemCount = pageSize, EnableScanInQuery = allowScan, EnableCrossPartitionQuery = true }).AsDocumentQuery(); while (docQuery.HasMoreResults) { DateTime startTime = DateTime.Now; DocumentFeedResponse <dynamic> queryResultsPage = await QueryWithRetry(docQuery, query.ToString()); activityIDsAllQueryPages.Add(queryResultsPage.ActivityId); totalQueryLatencyAllPages += (DateTime.Now - startTime); foreach (JObject result in queryResultsPage) { queriedDocuments.Add(result.ToString(Formatting.None)); } } numberOfQueries++; bool valid; var expected = Validate(queriedDocuments, query, out valid); if (!valid) { System.Diagnostics.Trace.TraceInformation( DateTime.Now.ToString("HH:mm:ss.ffff") + @": Query {0} did not retrieve expected documents, query all pages activitiIDs: ({1})" + Environment.NewLine + "Expected:" + Environment.NewLine + "{2}" + Environment.NewLine + "Actual:" + Environment.NewLine + "{3}" + Environment.NewLine, query.ToString(), String.Join(",", activityIDsAllQueryPages), String.Join(",", expected), String.Join(",", queriedDocuments)); failedQueries.Add(query); } } if (failedQueries.Count() == 0) { System.Diagnostics.Trace.TraceInformation(@"*** TEST PASSED ***"); return(0); } else { System.Diagnostics.Trace.TraceInformation(@"*** TEST FAILED with seed {0}***", seed); int result = -1; //In case of a failure, retry only failed queries after sleeping for couple of minutes. if (retries > 0) { System.Diagnostics.Trace.TraceInformation(@"*** Retrying Failed queries, {0} retries left ***", --retries); Task.Delay(120 * 1000).Wait(); result = await QueryAndVerifyDocuments(client, collectionLink, failedQueries, pageSize, retries, allowScan); } return(result); } }
/// <summary> /// Get the points near the specified point in the order of increasing distance using spatial queries. /// </summary> /// <param name="client"> /// The <see cref="DocumentClient"/> object. /// </param> /// <param name="documentCollectionLink"> /// The collection self link string. /// </param> /// <param name="propertyName"> /// The document property that stores GeoJSON. /// </param> /// <param name="point"> /// The specified <see cref="Point"/> of which to find the nearby points. /// </param> /// <param name="minDistance"> /// The minimum distance to start with (exclusive). /// </param> /// <param name="maxDistance"> /// The maximum distance to end with (inclusive). /// </param> /// <param name="maxPoints"> /// The maximum number of points to find. /// </param> public static IEnumerable <dynamic> Near(DocumentClient client, string documentCollectionLink, string propertyName, Point point, long minDistance, long maxDistance, int maxPoints) { // Validate arguments if (minDistance <= 0) { throw new ArgumentOutOfRangeException("Minimum distance must be a positive number."); } if (maxDistance < minDistance) { throw new ArgumentOutOfRangeException("Maximum distance must be greater than or equal to minimum distance."); } if (maxPoints <= 0) { throw new ArgumentOutOfRangeException("Max points must be positive."); } List <dynamic> totalPoints = new List <dynamic>(maxPoints); // Use parametrized query // Note: We do a SELECT r here. You may want to modify this and select specified properties. string queryFormat = @"SELECT r AS doc, ST_DISTANCE(r.{0}, @loc) AS distance FROM Root r WHERE ST_DISTANCE(r.{0}, @loc) BETWEEN @min AND @max"; string queryString = String.Format(queryFormat, propertyName); for (long distance = minDistance, previousDistance = 0; distance <= maxDistance; distance = Math.Min(2 * distance, maxDistance)) { SqlQuerySpec spec = new SqlQuerySpec() { QueryText = queryString, Parameters = new SqlParameterCollection() { new SqlParameter() { Name = "@loc", Value = point }, new SqlParameter() { Name = "@min", Value = previousDistance }, new SqlParameter() { Name = "@max", Value = distance } } }; IDocumentQuery <dynamic> query = client.CreateDocumentQuery(documentCollectionLink, spec).AsDocumentQuery(); while (query.HasMoreResults) { // Fetch results using ExecuteWithRetries in case of throttle. FeedResponse <dynamic> result = ExecuteWithRetries(() => query.ExecuteNextAsync()).Result; totalPoints.AddRange(result); } // Using BETWEEN can give us duplicate results. Here we remove them. totalPoints.GroupBy(result => result.doc.id).Select(group => group.First()); // Break once we have found enough points if (totalPoints.Count >= maxPoints) { break; } // Break once we reach the maximum distance to search if (distance == maxDistance) { break; } previousDistance = distance; } // Sort the results based on distance totalPoints.Sort((point1, point2) => { int cmp = point1.distance.CompareTo(point2.distance); return(cmp != 0 ? cmp : point1.doc.id.CompareTo(point2.doc.id)); }); foreach (dynamic result in totalPoints.Take(maxPoints)) { yield return(result.doc); } }
/// <summary> /// Run the get started application. /// </summary> /// <param name="client">The DocumentDB client instance</param> /// <returns>A Task for asynchronous execuion.</returns> public async Task RunAsync(DocumentClient client) { Database database = await client.CreateDatabaseIfNotExistsAsync(new Database { Id = "graphdb" }); DocumentCollection graph = await client.CreateDocumentCollectionIfNotExistsAsync( UriFactory.CreateDatabaseUri("graphdb"), new DocumentCollection { Id = "graphcollz" }, new RequestOptions { OfferThroughput = 1000 }); // Azure Cosmos DB supports the Gremlin API for working with Graphs. Gremlin is a functional programming language composed of steps. // Here, we run a series of Gremlin queries to show how you can add vertices, edges, modify properties, perform queries and traversals // For additional details, see https://aka.ms/gremlin for the complete list of supported Gremlin operators Dictionary <string, string> gremlinQueries = new Dictionary <string, string> { { "Cleanup", "g.V().drop()" }, { "AddVertex 1", "g.addV('person').property('id', 'thomas').property('firstName', 'Thomas').property('age', 44)" }, { "AddVertex 2", "g.addV('person').property('id', 'mary').property('firstName', 'Mary').property('lastName', 'Andersen').property('age', 39)" }, { "AddVertex 3", "g.addV('person').property('id', 'ben').property('firstName', 'Ben').property('lastName', 'Miller')" }, { "AddVertex 4", "g.addV('person').property('id', 'robin').property('firstName', 'Robin').property('lastName', 'Wakefield')" }, { "AddEdge 1", "g.V('thomas').addE('knows').to(g.V('mary'))" }, { "AddEdge 2", "g.V('thomas').addE('knows').to(g.V('ben'))" }, { "AddEdge 3", "g.V('ben').addE('knows').to(g.V('robin'))" }, { "UpdateVertex", "g.V('thomas').property('age', 44)" }, { "CountVertices", "g.V().count()" }, { "Filter Range", "g.V().hasLabel('person').has('age', gt(40))" }, { "Project", "g.V().hasLabel('person').values('firstName')" }, { "Sort", "g.V().hasLabel('person').order().by('firstName', decr)" }, { "Traverse", "g.V('thomas').out('knows').hasLabel('person')" }, { "Traverse 2x", "g.V('thomas').out('knows').hasLabel('person').out('knows').hasLabel('person')" }, { "Loop", "g.V('thomas').repeat(out()).until(has('id', 'robin')).path()" }, { "DropEdge", "g.V('thomas').outE('knows').where(inV().has('id', 'mary')).drop()" }, { "CountEdges", "g.E().count()" }, { "DropVertex", "g.V('thomas').drop()" }, }; foreach (KeyValuePair <string, string> gremlinQuery in gremlinQueries) { Console.WriteLine($"Running {gremlinQuery.Key}: {gremlinQuery.Value}"); // The CreateGremlinQuery method extensions allow you to execute Gremlin queries and iterate // results asychronously IDocumentQuery <dynamic> query = client.CreateGremlinQuery <dynamic>(graph, gremlinQuery.Value); while (query.HasMoreResults) { foreach (dynamic result in await query.ExecuteNextAsync()) { Console.WriteLine($"\t {JsonConvert.SerializeObject(result)}"); } } Console.WriteLine(); } // Data is returned in GraphSON format, which be deserialized into a strongly-typed vertex, edge or property class // The following snippet shows how to do this string gremlin = gremlinQueries["AddVertex 1"]; Console.WriteLine($"Running Add Vertex with deserialization: {gremlin}"); IDocumentQuery <Vertex> insertVertex = client.CreateGremlinQuery <Vertex>(graph, gremlinQueries["AddVertex 1"]); while (insertVertex.HasMoreResults) { foreach (Vertex vertex in await insertVertex.ExecuteNextAsync <Vertex>()) { // Since Gremlin is designed for multi-valued properties, the format returns an array. Here we just read // the first value string name = (string)vertex.GetVertexProperties("firstName").First().Value; Console.WriteLine($"\t Id:{vertex.Id}, Name: {name}"); } } Console.WriteLine(); Console.WriteLine("Done. Press any key to exit..."); Console.ReadLine(); }
private static async Task LoadAirports(DocumentClient client, DocumentCollection graph) { var retryPolicy = Policy .Handle <Exception>() .RetryAsync(5); var airports = new Dictionary <string, Airport>(); var routes = new HashSet <Tuple <string, string> >(); using (var httpClient = new HttpClient()) { var airportsCsvStream = await httpClient.GetStreamAsync("https://raw.githubusercontent.com/jpatokal/openflights/master/data/airports.dat"); using (var fileStream = new FileStream("airports.dat", FileMode.Create, FileAccess.Write)) { await airportsCsvStream.CopyToAsync(fileStream); airportsCsvStream.Close(); } using (var fileStream = new FileStream("airports.dat", FileMode.Open)) using (var reader = new CsvReader(new StreamReader(fileStream))) { var count = 0; while (reader.Read()) { var city = Regex.Replace(reader.GetField(2), @"[^\w']", "").Replace("'", @"\'"); var country = Regex.Replace(reader.GetField(3), @"[^\w']", "").Replace("'", @"\'"); var code = reader.GetField(4); var lat = reader.GetField(6); var lng = reader.GetField(7); if (!new string[] { @"\N", "N/A", "" }.Contains(code)) { var gremlinQuery = $"g.addV('airport').property('id', \"{code}\").property('latitude', {lat}).property('longitude', {lng}).property('city', '{city}').property('country', '{country}')"; var airport = new Airport { Code = code, Name = city, Coordinate = new GeoCoordinate(Convert.ToDouble(lat), Convert.ToDouble(lng)) }; airports.Add(code, airport); IDocumentQuery <dynamic> query = client.CreateGremlinQuery <dynamic>(graph, gremlinQuery); count++; await retryPolicy .ExecuteAsync(async() => { System.Console.WriteLine($"{count} {gremlinQuery}"); await query.ExecuteNextAsync(); }); } } } var routesCsvStream = await httpClient.GetStreamAsync("https://raw.githubusercontent.com/jpatokal/openflights/master/data/routes.dat"); using (var fileStream = new FileStream("routes.dat", FileMode.Create, FileAccess.Write)) { await routesCsvStream.CopyToAsync(fileStream); routesCsvStream.Close(); } using (var fileStream = new FileStream("routes.dat", FileMode.Open)) using (var reader = new CsvReader(new StreamReader(fileStream))) { var count = 0; while (reader.Read()) { var airline = reader.GetField(0); var from = reader.GetField(2); var to = reader.GetField(4); var stops = reader.GetField(7); if (string.IsNullOrEmpty(from) || string.IsNullOrEmpty(to)) { continue; } var route = Tuple.Create(from, to); airports.TryGetValue(from, out var fromAirport); airports.TryGetValue(to, out var toAirport); var isDirect = stops == "0"; if (isDirect && !routes.Contains(route) && fromAirport != null && toAirport != null) { routes.Add(route); var distance = fromAirport.Coordinate.GetDistanceTo(toAirport.Coordinate); var gremlinQuery = $"g.V('{fromAirport.Code}').addE('flight').to(g.V('{toAirport.Code}')).property('distance', {distance})"; IDocumentQuery <dynamic> query = client.CreateGremlinQuery <dynamic>(graph, gremlinQuery); count++; await retryPolicy .ExecuteAsync(async() => { System.Console.WriteLine($"{count} {gremlinQuery}"); await query.ExecuteNextAsync(); }); } } } } }
public DocumentsController(IServiceBus serviceBus, ITransactionScopeFactory transactionScopeFactory, IDatabaseContextFactory databaseContextFactory, IDocumentRepository documentRepository, IDocumentQuery documentQuery) { Guard.AgainstNull(serviceBus, nameof(serviceBus)); Guard.AgainstNull(transactionScopeFactory, nameof(transactionScopeFactory)); Guard.AgainstNull(databaseContextFactory, nameof(databaseContextFactory)); Guard.AgainstNull(documentRepository, nameof(documentRepository)); Guard.AgainstNull(documentQuery, nameof(documentQuery)); _serviceBus = serviceBus; _transactionScopeFactory = transactionScopeFactory; _databaseContextFactory = databaseContextFactory; _documentRepository = documentRepository; _documentQuery = documentQuery; }
/// <summary> /// Creates a query to the Change Feed. /// </summary> /// <param name="collectionLink">Collection Self Link.</param> /// <param name="feedOptions">An instance of <see cref="FeedOptions"/>.</param> /// <returns>A query response to transverse.</returns> public IChangeFeedDocumentQuery <Document> CreateDocumentChangeFeedQuery(string collectionLink, ChangeFeedOptions feedOptions = null) { IDocumentQuery <Document> query = this.documentClient.CreateDocumentChangeFeedQuery(collectionLink, feedOptions); return(new ChangeFeedDocumentQuery <Document>(query)); }
/// <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); }
private static async Task <int> DeleteDocumentsInQueryAsync <T>(IDocumentClient client, IDocumentQuery <T> query) { var linksToDelete = new List <string>(); while (query.HasMoreResults) { var documents = await query.ExecuteNextAsync <Document>().ConfigureAwait(false); linksToDelete.AddRange(documents.Select(d => d.SelfLink)); } foreach (var link in linksToDelete) { await client.DeleteDocumentAsync(link).ConfigureAwait(false); } return(linksToDelete.Count); }
public static async Task <IActionResult> Run( [HttpTrigger(AuthorizationLevel.Function, "post", Route = null)] HttpRequest req, [CosmosDB( databaseName: "QuestionsData", collectionName: "QuestionsData", ConnectionStringSetting = "QuestionsDBConnection")] DocumentClient questionsTable, [CosmosDB( databaseName: "UserInformation", collectionName: "UserInformation", ConnectionStringSetting = "UserInformationDBConnection")] DocumentClient usersTable, ILogger log) { log.LogInformation("Start updating riskinformation."); Tokens tokens = null; try { tokens = await System.Text.Json.JsonSerializer.DeserializeAsync <Tokens>(req.Body, new JsonSerializerOptions() { AllowTrailingCommas = true, } ); } catch (System.Text.Json.JsonException ex) { return(new BadRequestObjectResult($"There was an error in the provided json: {ex.Message} -> {ex.InnerException.Message}")); } Uri questionsCollectionUri = UriFactory.CreateDocumentCollectionUri("QuestionsData", "QuestionsData"); Uri userCollectionUri = UriFactory.CreateDocumentCollectionUri("UserInformation", "UserInformation"); log.LogInformation("Try to get question and user information."); IDocumentQuery <QuestionData> questionsQuery = questionsTable.CreateDocumentQuery <QuestionData>(questionsCollectionUri, new FeedOptions() { EnableCrossPartitionQuery = true }) .Where(p => p.Token == tokens.QuestionToken) .AsDocumentQuery <QuestionData>(); IDocumentQuery <Shared.Models.UserInformation> userQuery = usersTable.CreateDocumentQuery <Shared.Models.UserInformation>(userCollectionUri, new FeedOptions() { EnableCrossPartitionQuery = true }) .Where(p => p.Token == tokens.UserToken) .AsDocumentQuery <Shared.Models.UserInformation>(); if (!questionsQuery.HasMoreResults) { return(new BadRequestObjectResult($"Your provided question token is not valid: {tokens.QuestionToken}")); } if (!userQuery.HasMoreResults) { return(new BadRequestObjectResult($"Your provided user token is not valid: {tokens.UserToken}")); } var questionResult = await questionsQuery.ExecuteNextAsync <QuestionData>(); var questionData = questionResult.First(); var userResult = await userQuery.ExecuteNextAsync <Shared.Models.UserInformation>(); var userData = userResult.First(); log.LogInformation($"Update risk level of user {tokens.UserToken}"); userData.RiskScore = questionData.RiskScore; await usersTable.ReplaceDocumentAsync(UriFactory.CreateDocumentUri("UserInformation", "UserInformation", userData.Id), userData); log.LogInformation($"Successful updated risk level of the user {tokens.UserToken}"); return(new OkObjectResult(new UserInformationViewModel(userData))); }
IEnumerator <TimeSeriesStreamResult <TimeSeriesAggregationResult> > ITimeSeriesSessionStreamOperations <TimeSeriesAggregationResult> .Stream(IDocumentQuery <TimeSeriesAggregationResult> query, out StreamQueryStatistics streamQueryStats) { return(StreamTimeSeriesInternal(query, out streamQueryStats)); }
private async Task <int> QueryAndVerifyDocuments(int pageSize = 1000) { Random rnd = new Random(); TimeSpan totalQueryLatencyAllPages = TimeSpan.FromSeconds(0); int numberOfPages = 0; int numberOfQueries = 0; int resultCount = 0; bool anyFailures = false; foreach (KeyValuePair <SqlKeyValueQueryBuilder, HashSet <string> > keyVal in this.invertedIndex) { HashSet <string> idSet = new HashSet <string>(); List <string> activityIDsAllQueryPages = new List <string>(); string query = keyVal.Key.GetQuery(); if (this.invertedIndex.Count > targetNumberOfQueriesToValidate) { double percentageOfQueriesToExecute = targetNumberOfQueriesToValidate / (1.0 * this.invertedIndex.Count); if (rnd.NextDouble() > percentageOfQueriesToExecute) { continue; } } if (numberOfQueries > 0 && numberOfQueries % 100 == 0) { System.Diagnostics.Trace.TraceInformation(DateTime.Now.ToString("HH:mm:ss.ffff") + @": Executing query {0} of {1}", (numberOfQueries + 1), this.invertedIndex.Count); System.Diagnostics.Trace.TraceInformation(@" Query latency per page (avg ms) {0} after {1} pages", totalQueryLatencyAllPages.TotalMilliseconds / numberOfPages, numberOfPages); System.Diagnostics.Trace.TraceInformation(@" Query latency per query (avg ms) {0} after {1} queries", totalQueryLatencyAllPages.TotalMilliseconds / numberOfQueries, numberOfQueries); System.Diagnostics.Trace.TraceInformation(@" Number of results per page {0} after {1} pages", resultCount / (double)numberOfPages, numberOfPages); System.Diagnostics.Trace.TraceInformation(@" Number of results per query {0} after {1} queries", resultCount / (double)numberOfQueries, numberOfQueries); } IDocumentQuery <dynamic> docQuery = client.CreateDocumentQuery(collectionLink, query, feedOptions: new FeedOptions { MaxItemCount = pageSize }).AsDocumentQuery(); while (docQuery.HasMoreResults) { DateTime startTime = DateTime.Now; FeedResponse <dynamic> queryResultsPage = await QueryOnePageWithRetry(docQuery, query); activityIDsAllQueryPages.Add(queryResultsPage.ActivityId); totalQueryLatencyAllPages += (DateTime.Now - startTime); numberOfPages++; foreach (JObject result in queryResultsPage) { resultCount++; string id = result["_rid"].ToString(); if (!keyVal.Value.Contains(id)) { System.Diagnostics.Trace.TraceInformation( DateTime.Now.ToString("HH:mm:ss.ffff") + @": The doc id {0} for query {1} was not expected in the results, query activityId: {2}", id, query, queryResultsPage.ActivityId); anyFailures = true; continue; } if (idSet.Contains(id)) { System.Diagnostics.Trace.TraceInformation( DateTime.Now.ToString("HH:mm:ss.ffff") + @": Same document id {0} returned twice for query ({1}), query activityId: {2}", id, query, queryResultsPage.ActivityId); anyFailures = true; } else { idSet.Add(id); } } } numberOfQueries++; foreach (string queryOracleId in keyVal.Value) { if (!idSet.Contains(queryOracleId)) { System.Diagnostics.Trace.TraceInformation( DateTime.Now.ToString("HH:mm:ss.ffff") + @": The doc id {0} was expected for query {1} but was not obtained, query all pages activitiIDs: ({2})", queryOracleId, query, String.Join(",", activityIDsAllQueryPages)); if (!failedQueries.ContainsKey(keyVal.Key)) { failedQueries.Add(keyVal.Key, keyVal.Value); } anyFailures = true; continue; } } } if (!anyFailures) { System.Diagnostics.Trace.TraceInformation(@"*** TEST PASSED ***"); return(0); } else { System.Diagnostics.Trace.TraceInformation(@"*** TEST FAILED ***"); int result = -1; //In case of a failure, retry only failed queries after sleeping for couple of minutes. if (enableRetries && this.retryCount < 10) { System.Diagnostics.Trace.TraceInformation(String.Format(CultureInfo.InvariantCulture, @"*** Retrying {0} Failed queries ***", failedQueries.Count)); this.retryCount++; Task.Delay(120 * 1000).Wait(); result = await this.RetryFailedQueries(pageSize); } return(result); } }
IEnumerator <TimeSeriesStreamResult <TimeSeriesRawResult <T> > > ITimeSeriesSessionStreamRawResultOperations.Stream <T>(IDocumentQuery <TimeSeriesRawResult <T> > query) { return(StreamTimeSeriesInternal(query)); }
public IEnumerator <StreamResult <T> > Stream <T>(IDocumentQuery <T> query, out QueryHeaderInformation queryHeaderInformation) { throw new NotSupportedException("Streams are currently not supported by sharded document store"); }
private static async Task <int> BackUpCollection(CloudStorageAccount storageAccount, DateTime starttime) { Uri collectionURI = UriFactory.CreateDocumentCollectionUri(DatabaseName, CollectionName); //Our changes file daily roll example CloudBlobClient blobClient = storageAccount.CreateCloudBlobClient(); //Setup our container we are going to use and create it. CloudBlobContainer container = blobClient.GetContainerReference("dbchanges"); await container.CreateIfNotExistsAsync(); DateTime changefiledate = DateTime.Today; CloudAppendBlob appBlob = container.GetAppendBlobReference( string.Format("{0}_{1}_{2}{3}", DatabaseName, CollectionName, changefiledate.ToString("yyyyMMdd"), ".json")); var exists = await appBlob.ExistsAsync(); if (!exists) { await appBlob.CreateOrReplaceAsync(); await appBlob.AppendTextAsync("["); //Store file as JSON Array for easy import } int x = 0; string pkRangesResponseContinuation = null; using (var client = new DocumentClient(new Uri(endpointUrl), authorizationKey, new ConnectionPolicy { ConnectionMode = ConnectionMode.Direct, ConnectionProtocol = Protocol.Tcp })) { var pkRangesResponse = await client.ReadPartitionKeyRangeFeedAsync(collectionURI, new FeedOptions { RequestContinuation = pkRangesResponseContinuation }); List <PartitionKeyRange> partitionKeyRanges = new List <PartitionKeyRange>(); partitionKeyRanges.AddRange(pkRangesResponse); pkRangesResponseContinuation = pkRangesResponse.ResponseContinuation; Dictionary <string, string> checkpoints = new Dictionary <string, string>(); bool comma = exists; foreach (PartitionKeyRange pkRange in partitionKeyRanges) { string continuation = null; checkpoints.TryGetValue(pkRange.Id, out continuation); IDocumentQuery <Document> query = client.CreateDocumentChangeFeedQuery( collectionURI, new ChangeFeedOptions { PartitionKeyRangeId = pkRange.Id, StartFromBeginning = true, RequestContinuation = continuation, MaxItemCount = -1, // Set reading time: only show change feed results modified since StartTime StartTime = starttime }); while (query.HasMoreResults) { FeedResponse <dynamic> readChangesResponse = query.ExecuteNextAsync <dynamic>().Result; foreach (dynamic changedDocument in readChangesResponse) { Console.WriteLine("document: {0}", changedDocument); await appBlob.AppendTextAsync((comma ? "," : "") + changedDocument); x++; comma = true; } checkpoints[pkRange.Id] = readChangesResponse.ResponseContinuation; } } } return(x); }
public AttachmentApiController( IDocumentQuery<Attachment> documentQuery) { _documentQuery = documentQuery; }