Tuesday, April 23, 2019

Introduction to Continuation tokens in Azure CosmosDB


      To understand what Continuation does in Azure CosmosDB, Let's look at how SQL Server handles query results first and try to compare SQL Server to CosmosDB. If you will run the following select statement in SQL Server. You will end up with all the data Orders table has. If there are 1 million rows, SQL Server will try to deliver 1 million rows to you like a warrior. You can use TOP statement if you want to see only top x rows, but that's optional.

SELECT Name, Age FROM Orders

      In CosmosDB, TOP option is required and its default value is 100. You can change the default value by sending a different value using the request header "x-ms-max-item-count". If you have 40000 rows in your Orders table, and run the same query in CosmosDB, you will get 100 rows(documents) rather than 40000 rows(documents). CosmosDB returns all kind of metadata with the data. You can find this metadata in the response headers. One of those responses is, "x-ms-continuation" and it is responsible to display the rest of the rows of your query. If you like to get the next set of results, you can take "x-ms-continuation" value from the response headers and attach it to your next request to get the next set of rows. CosmosDB SDK does this automatically for you. SDK checks for the x-ms-continuation value when you check HasMoreResults property. If this property is true, that means CosmosDB returned a continuation token.

      In the following example; I am using POSTMAN, CosmosDB Emulator and CosmosDB Rest API to demo continuation in CosmosDB. First, I am going to override the request header "x-ms-max-item-count" and I am going to give value 10. Basically, by overriding this property with 10, I am saying return me TOP 10 results. If there are more than 10 rows(documents) in my table(container), CosmosDB should return first 10 rows(documents) with a continuation token which references the next 10 rows.


This is the query I want to run in my local CosmosDB, I need to attach it to the body part of the request. You can find write your query under Body tab in POSTMAN



      I see the following screen when I click Send. As you can see we received 10 documents and 29 properties about the query in Headers tab. One of those 29 properties should be a continuation token.


Click on Headers link to see all the CosmosDB responses. 



    All we have to do is, copy the value of x-ms-continuation and add it to our next request.


Click on Send again, we will have the next set of results.



      We need to talk about another option named RequestTimeOut of CosmosDB since we are talking about the continuation tokens. This option is used for continuation token timeouts. It will get reset everytime you use a continuation token. For example, let's say our RequestTimeOut is 2 seconds and MaxItemCount is 100. Our query returns 1000 rows, that means we need to visit CosmosDB 10 times to retrieve all the data. Each time we visit CosmosDB, RequestTimeOut will get reset to 0.  So If it takes 0.5 seconds to retrieve 100 rows, total will take 5 seconds but since everytime RequestTimeout gets reset to 0, we will not see any TimeOut errors.

1 comment:

  1. Can we get (total number/count) of the records which will be resulted with respective to that query irrespective of max-items-count

    ReplyDelete