Azure DocumentDB Demo

December the 1st, 2015, I’m doing a presentation to a Montreal User Group, MS DEV MTL. Here is the script of each demo.  Enjoy!

UPDATE:  You can see the presentation slides here.

 

Account Creation & Adding Documents

For the creation of an Azure DocumentDB account, allow me to refer to myself in Creating an Azure DocumentDB account.

In order to add a database, in your DocumentDB account blade, click “Add Database”, name it Demo-DB.

Select that database ; that will open the database blade. Click “Add Collection”, name it demo. Change the price tier to S1.

Select the collection you just created. That will open the collection blade. We are going to create two documents. For that, click “Create Document” on top of the collection blade. First document:

{
"firstName" : "Vincent-Philippe",
"lastName" : "Lauzon",
"office" : "MTL"
}

Second document:

{
"office" : "MTL",
"address" :
{
"streetNumber" : 2000,
"streetName" : "McGill College",
"streetType" : "Avenue",
"inBuilding" : "Suite 500",
"postalCode" : "H3A 3H3"
}
}

Now, let’s look at those document within the collection. In the collection blade, click “Document Explorer” (at the bottom). You will notice a few things:

Let’s add a third document:

{
"firstName" : "John",
"lastName" : "Smith",
"office" : "Calgary",
"id" : "emp-john-smith",
"phoneNumber" : "123-456-7890"
}

You can go ahead and look at the document and observe that:

Simple Querying

For querying, in the collection blade, click “Query Explorer”. Leave the query as is, i.e.

 

SELECT * FROM c

 

Let’s observe a few things:

Let’s try something slightly less trivial:

 

SELECT *
FROM c
WHERE c.firstName != null

 

Now we have only the employees, i.e. we skipped the MTL office document.

The following query does a projection or a JSON transformation:

 

SELECT
{"firstName":c.firstName, "lastName":c.lastName} AS name,
c.office
FROM c
WHERE c.firstName!=null

 

This yields the following results:

[
{
 "name": {
 "firstName": "Vincent-Philippe",
 "lastName": "Lauzon"
 },
 "office": "MTL"
 },
 {
 "name": {
 "firstName": "John",
 "lastName": "Smith"
 },
 "office": "Calgary"
 }
]

 

This demonstrates how DocumentDB merges the power of T-SQL with the JavaScript language seamlessly.

To explore more about querying, go to the querying playground where you can explore interactively (web browser).

Indexing Policy

To look at the current indexing policy of a collection, in the collection blade, click “Indexing Policy”. Typically, you’ll see the following:

 

{
 "indexingMode": "consistent",
 "automatic": true,
 "includedPaths": [
 {
 "path": "/*",
 "indexes": [
 {
 "kind": "Range",
 "dataType": "Number",
 "precision": -1
 },
 {
 "kind": "Hash",
 "dataType": "String",
 "precision": 3
 },
 {
 "kind": "Spatial",
 "dataType": "Point"
 }
 ]
 },
 {
 "path": "/\"_ts\"/?",
 "indexes": [
 {
 "kind": "Range",
 "dataType": "Number",
 "precision": -1
 },
 {
 "kind": "Hash",
 "dataType": "String",
 "precision": 3
 }
 ]
 }
 ],
 "excludedPaths": []
}

 

where you can observe

Looking at consistency level

Go in you DocumentDB account blade, at the bottom, in “Configuration”, click “Default consistency”.

You can actually see the definitions of each level in the portal.

SDK Demo

Start up a new Console App project. Get the NuGet package Microsoft.Azure.DocumentDB.

Everything orbits around the DocumentClient component. To instantiate one, you need information from your DocumentDB account. In the account blade, click the key icon.

You’ll need:

In the code, simply instantiate it as:

private static readonly DocumentClient _docClient = new DocumentClient(
new Uri(ENDPOINT),
AUTH_KEY,
ConnectionPolicy.Default,
ConsistencyLevel.Session);

Here you see that you can override the connection policy (see this post for details) and the consistency level for the connection.

The rest of the code will use the method “QueryAsync” defined in this post.

First, let’s find our collection, in purely scalable way:

  ```csharp private async static Task GetCollectionAsync() { var dbQuery = from db in _docClient.CreateDatabaseQuery() where db.Id == DB_NAME select db; var database = (await QueryAsync(dbQuery)).FirstOrDefault(); var collectionQuery = from col in _docClient.CreateDocumentCollectionQuery(database.AltLink) where col.Id == COLLECTION_NAME select col; var collection = (await QueryAsync(collectionQuery)).FirstOrDefault(); return collection; } ```   </div>
What we do here is basically search our database among databases within the account by querying the database list, then do the same thing with collection.
The interesting points to notice here is that we do everything async, including querying. There is nothing blocking here.
Let's define an employee object, a PONO:
```csharp public class Employee { [JsonProperty("id")] public string ID { get; set; } [JsonProperty("firstName")] public string FirstName { get; set; } [JsonProperty("lastName")] public string LastName { get; set; } [JsonProperty("office")] public string Office { get; set; } [JsonProperty("phoneNumber")] public string PhoneNumber { get; set; } } ```
Here we use attributes to map property names to bridge the gap of JavaScript and C# in terms of naming convention, i.e. the fact that JavaScript typically starts with lowercase while C# starts with uppercase. Other approach could have been used.
Let's define a method to find me:
  ```csharp private async static Task QueryVinceAsync(DocumentCollection collection) { var employees = from e in _docClient.CreateDocumentQuery(collection.SelfLink) where e.FirstName == "Vincent-Philippe" select e; var vincent = (await QueryAsync(employees)).FirstOrDefault(); return vincent; } ```   </div> </div>
Here, we again do a query, this time on documents within a collection. We strong type the query for employee's type. That doesn't filter out non-employees though. The filter on the query does that: it searches for document having a property firstName being equaled to Vincent-Philippe. Document without such a property obviously fail that filter.
Then we can look at the code of the demo:
  ```csharp private static async Task DemoAsync() { var collection = await GetCollectionAsync(); var vincent = await QueryVinceAsync(collection); var newEmployee = new Employee { FirstName = "Jessica", LastName = "Jones", Office = "Hell's Kitchen", PhoneNumber = "Unknown" }; var newEmployeeResponse = await _docClient.CreateDocumentAsync(collection.SelfLink, newEmployee); // ID of the created employee document Console.WriteLine(newEmployeeResponse.Resource.Id); } ```  
Interesting point here is the return type of document creation method. Since the SDK is a thin wrapper around REST calls, the return type returns all the stuff returned by the REST call. Of interest: newEmployeeResponse.RequestCharge. This is 6.1 and this is in Request Units (RUs). This helps you figure out the pricing tier you should look after.
 

Leave a comment