DocumentDB

Jax ARCSIG October 2014

I am David Fekke

  • .NET Developer by day
  • Develop iOS and Android apps
  • Node.js
  • MomentStrong

The Jax Tech Meetups App

  • iOS just released
  • Android coming soon
  • Looking for volunteers for Windows Phone
  • jaxtechmeetups.com
  • Site mobile friendly

Push

  • Important feature in most mobile OSes
  • Each phone has a unique identifier (token) for push
  • Have to store token somewhere

Persisting Tokens

  • Host a http service
  • Store token as persistent data
  • Be able to easily query tokens

Azure Persistence options

  • SQL Server
  • MySQL
  • Azure DataTables
  • MongoDB
  • DocumentDB (Beta)

About DocumentDB

  • Document Database
  • Documents stored in JSON format
  • Query with SQL like syntax
  • Works well with .NET and Node.js
  • Create Stored Procedures in JS

Features

  • Rich query over a schema-free JSON data model
  • Transactional execution of JavaScript logic
  • Scalable storage and throughput
  • Tunable consistency
  • Rapid development with familiar technologies
  • Blazingly fast and write optimized database service

Getting Started

  • Create DB account
  • Grab Endpoint and Key for your code 
  • Create Database
  • Create Document Collection in your DB
  • Create a Document

Sample Document

{
	id: 456123,
	FirstName: "David",
	LastName: "Fekke",
	EmployeeNumber: 786789
}

Query a Document

    "SELECT e.id, e.FirstName  " +
    "FROM Employees e " +
    "WHERE e.EmployeeNumber = 4561518"

DocumentDB platforms

  • .NET
  • Node.js
  • Python

.NET

private static string EndpointUrl = "<your endpoint URI>";
private static string AuthorizationKey = "<your key>";

// Create a new instance of the DocumentClient
var client = new DocumentClient(new Uri(EndpointUrl), AuthorizationKey); 

// Create a Database
Database database = await client.CreateDatabaseAsync(
    new Database
        {
            Id = "FamilyRegistry"
        });

// Create a document collection
DocumentCollection documentCollection = await client
    .CreateDocumentCollectionAsync(database.CollectionsLink,
    new DocumentCollection
        {
            Id = "FamilyCollection"
        });

.NET

// Create the WakeField Family document
Family wakefieldFamily = new Family
{
    Id = "WakefieldFamily",
    Parents = new Parent[] {
        new Parent { FamilyName= "Wakefield", FirstName= "Robin" },
        new Parent { FamilyName= "Miller", FirstName= "Ben" }
    },
    Children = new Child[] {
        new Child {
            FamilyName= "Merriam", 
            FirstName= "Jesse", 
            Gender= "female", 
            Grade= 8,
            Pets= new Pet[] {
                new Pet { GivenName= "Goofy" },
                new Pet { GivenName= "Shadow" }
            }
        }
    },
    Address = new Address { State = "NY", County = "Manhattan", City = "NY" },
    IsRegistered = false
};

await client.CreateDocumentAsync(documentCollection.DocumentsLink, 
    wakefieldFamily);
// Query the documents using DocumentDB SQL for the Andersen family
var families = client.CreateDocumentQuery(documentCollection.DocumentsLink,
    "SELECT * " +
    "FROM Families f " +
    "WHERE f.id = \"AndersenFamily\"");

foreach (var family in families)
{
    Console.WriteLine("\tRead {0} from SQL", family);
}

// Query the documents using LINQ lambdas for the Andersen family
families = client.CreateDocumentQuery(documentCollection.DocumentsLink)
    .Where(f => f.Id == "AndersenFamily")
    .Select(f => f);

foreach (var family in families)
{
    Console.WriteLine("\tRead {0} from LINQ query", family);
}

.NET

Node.js

// import the modules we will use
var DocumentDBClient = require('documentdb').DocumentClient;
var nconf = require('nconf');

// tell nconf which config file to use
nconf.env();
nconf.file({ file: 'config.json' });

//config.json
{
    "HOST"       : "<insert your DocDB endpoint here>",
    "AUTH_KEY"   : "<insert either primary or secondary key here>",
    "DATABASE"   : "ToDoList",
    "COLLECTION" : "Items"
}

Node.js

// create an instance of the DocumentDB client
var client = new DocumentDBClient(host, { masterKey: authKey });

//Boilerplate functions
function readOrCreateDatabase(callback) {
    client.queryDatabases('SELECT * FROM root r WHERE r.id="' + 
        databaseId + '"').toArray(function (err, results) {
        if (err) {
            // some error occured, rethrow up
            throw (err);
        }
        if (!err && results.length === 0) {
            // no error occured, but there were no results returned 
            // indicating no database exists matching the query            
            client.createDatabase({ id: databaseId }, 
                function (err, createdDatabase) {
                    callback(createdDatabase);
            });
        } else {
            // we found a database
            callback(results[0]);
        }
    });
}

Node.js

client.queryDocuments(collection._self, 
       'SELECT * FROM tokens t WHERE t.id = "' + req.body.id + '"')
       .toArray(function (err, docs) {
	if (err) {
		throw (err);
	}
	if (docs.length == 0)
	{
		client.createDocument(collection._self, documentDefinition, 
                    function(err, document) {
		if(err) return console.log(err);

		console.log('Created Document with content: ', document.id);
	});
	} else {
        	console.log("Document already exists");
	}
});

Server Code

  • Stored Procedures
  • Triggers
  • UDFs

Demo

Questions

Contact Me

  • David Fekke at gmail dot com
  • Twitter: @davidfekke & @jaxnode
  • Skype: davidfekke