title: DocumentDB Change Feed and saving Checkpoint
body: <p>After reading the documentation, I'm having a hard time conceptualizing the change feed.  Let's take the code from the <a href="https://docs.microsoft.com/en-us/azure/documentdb/documentdb-change-feed" rel="nofollow noreferrer">documentation</a> below.  The second change feed is picking up the changes from the last time it was run via the checkpoints.  Let's say it is being used to create summary data and there was an issue and it needed to be re-run from a prior time.  I don't understand the following:</p>
  
  <ul>
  <li>How to specify a particular time the checkpoint should start.  I understand I can save the checkpoint dictionary and use that for each run, but how do you get the changes from X time to maybe rerun some summary data</li>
  <li>Secondly, let's say we are rerunning some summary data and we save the last checkpoint used for each summarized data so we know where that one left off.   How does one know that a record is in or before that checkpoint?</li>
  </ul>
  
  <p>Code that runs from collection beginning and then from last checkpoint:</p>
  
  <pre><code>   Dictionary &lt; string, string &gt; checkpoints = await GetChanges(client, collection, new Dictionary &lt; string, string &gt; ());
  
    await client.CreateDocumentAsync(collection, new DeviceReading {
     DeviceId = "xsensr-201", MetricType = "Temperature", Unit = "Celsius", MetricValue = 1000
    });
    await client.CreateDocumentAsync(collection, new DeviceReading {
     DeviceId = "xsensr-212", MetricType = "Pressure", Unit = "psi", MetricValue = 1000
    });
  
    // Returns only the two documents created above.
    checkpoints = await GetChanges(client, collection, checkpoints);
    //
  
    private async Task &lt; Dictionary &lt; string, string &gt;&gt; GetChanges(
     DocumentClient client,
     string collection,
     Dictionary &lt; string, string &gt; checkpoints) {
     List &lt; PartitionKeyRange &gt; partitionKeyRanges = new List &lt; PartitionKeyRange &gt; ();
     FeedResponse &lt; PartitionKeyRange &gt; pkRangesResponse;
  
     do {
      pkRangesResponse = await client.ReadPartitionKeyRangeFeedAsync(collection);
      partitionKeyRanges.AddRange(pkRangesResponse);
     }
     while (pkRangesResponse.ResponseContinuation != null);
  
     foreach(PartitionKeyRange pkRange in partitionKeyRanges) {
      string continuation = null;
      checkpoints.TryGetValue(pkRange.Id, out continuation);
  
      IDocumentQuery &lt; Document &gt; query = client.CreateDocumentChangeFeedQuery(
       collection,
       new ChangeFeedOptions {
        PartitionKeyRangeId = pkRange.Id,
         StartFromBeginning = true,
         RequestContinuation = continuation,
         MaxItemCount = 1
       });
  
      while (query.HasMoreResults) {
       FeedResponse &lt; DeviceReading &gt; readChangesResponse = query.ExecuteNextAsync &lt; DeviceReading &gt; ().Result;
  
       foreach(DeviceReading changedDocument in readChangesResponse) {
        Console.WriteLine(changedDocument.Id);
       }
  
       checkpoints[pkRange.Id] = readChangesResponse.ResponseContinuation;
      }
     }
  
     return checkpoints;
    }
  </code></pre>