Node.js tutorial: DocumentDB Node.js console application

Welcome to the Node.js tutorial for the Azure Cosmos DB Node.js SDK! After following this tutorial, you'll have a console application that creates and queries Azure Cosmos DB resources.

We'll cover:

  • Creating and connecting to an Azure Cosmos DB account
  • Setting up your application
  • Creating a node database
  • Creating a collection
  • Creating JSON documents
  • Querying the collection
  • Replacing a document
  • Deleting a document
  • Deleting the node database

Don't have time? Don't worry! The complete solution is available on GitHub. See Get the complete solution for quick instructions.

After you've completed the Node.js tutorial, please use the voting buttons at the top and bottom of this page to give us feedback. If you'd like us to contact you directly, feel free to include your email address in your comments.

Now let's get started!

Prerequisites for the Node.js tutorial

Please make sure you have the following:

Step 1: Create an Azure Cosmos DB account

Let's create an Azure Cosmos DB account. If you already have an account you want to use, you can skip ahead to Setup your Node.js application. If you are using the Azure Cosmos DB Emulator, please follow the steps at Azure Cosmos DB Emulator to setup the emulator and skip ahead to Setup your Node.js application.

  1. In a new window, sign in to the Azure portal.
  2. In the left pane, click New, click Databases, and then click Azure Cosmos DB.

    The Azure portal Databases pane

  3. On the New account blade, specify the configuration that you want for the Azure Cosmos DB account.

    With Azure Cosmos DB, you can choose one of four programming models: Gremlin (graph), MongoDB, SQL (DocumentDB), and Table (key-value).

    In this quick-start article we program against the DocumentDB API, so choose SQL (DocumentDB) as you fill out the form. But if you have graph data for a social media app, or key/value (table) data, or data migrated from a MongoDB app, realize that Azure Cosmos DB can provide a highly available, globally distributed database service platform for all your mission-critical applications.

    Complete the fields on the New account blade, using the information in the following screenshot as a guide. When you set up your account, choose unique values that do not match those in the screenshot.

    The new Azure Cosmos DB blade

    Setting Suggested value Description
    ID Unique value A unique name that identifies your Azure Cosmos DB account. The string documents.azure.com is appended to the ID you provide to create your URI, so use a unique but identifiable ID. The ID can contain only lowercase letters, numbers, and the hyphen (-) character, and it must contain from 3 through 50 characters.
    API SQL (DocumentDB) We program against the DocumentDB API later in this article.
    Subscription Your subscription The Azure subscription that you want to use for your Azure Cosmos DB account.
    Resource Group The same value as ID The new resource-group name for your account. For simplicity, you can use the same name as your ID.
    Location The region closest to your users The geographic location in which to host your Azure Cosmos DB account. Choose the location that's closest to your users to give them the fastest access to the data.
  4. Click Create to create the account.
  5. On the top toolbar, click Notifications to monitor the deployment process.

    The Azure portal Notifications pane

  6. When the deployment is complete, open the new account from the All Resources tile.

    The DocumentDB account on the All Resources tile

Step 2: Setup your Node.js application

  1. Open your favorite terminal.
  2. Locate the folder or directory where you'd like to save your Node.js application.
  3. Create two empty JavaScript files with the following commands:
    • Windows:
      • fsutil file createnew app.js 0
      • fsutil file createnew config.js 0
    • Linux/OS X:
      • touch app.js
      • touch config.js
  4. Install the documentdb module via npm. Use the following command:
    • npm install documentdb --save

Great! Now that you've finished setting up, let's start writing some code.

Step 3: Set your app's configurations

Open config.js in your favorite text editor.

Then, copy and paste the code snippet below and set properties config.endpoint and config.primaryKey to your DocumentDB endpoint uri and primary key. Both these configurations can be found in the Azure Portal.

Node.js tutorial - Screen shot of the Azure Portal, showing an Azure Cosmos DB account, with the ACTIVE hub highlighted, the KEYS button highlighted on the Azure Cosmos DB account blade, and the URI, PRIMARY KEY and SECONDARY KEY values highlighted on the Keys blade - Node database

// ADD THIS PART TO YOUR CODE
var config = {}

config.endpoint = "~your DocumentDB endpoint uri here~";
config.primaryKey = "~your primary key here~";

Copy and paste the database id, collection id, and JSON documents to your config object below where you set your config.endpoint and config.authKey properties. If you already have data you'd like to store in your database, you can use Azure Cosmos DB's Data Migration tool rather than adding the document definitions.

config.endpoint = "~your DocumentDB endpoint uri here~";
config.primaryKey = "~your primary key here~";

// ADD THIS PART TO YOUR CODE
config.database = {
    "id": "FamilyDB"
};

config.collection = {
    "id": "FamilyColl"
};

config.documents = {
    "Andersen": {
        "id": "Anderson.1",
        "lastName": "Andersen",
        "parents": [{
            "firstName": "Thomas"
        }, {
                "firstName": "Mary Kay"
            }],
        "children": [{
            "firstName": "Henriette Thaulow",
            "gender": "female",
            "grade": 5,
            "pets": [{
                "givenName": "Fluffy"
            }]
        }],
        "address": {
            "state": "WA",
            "county": "King",
            "city": "Seattle"
        }
    },
    "Wakefield": {
        "id": "Wakefield.7",
        "parents": [{
            "familyName": "Wakefield",
            "firstName": "Robin"
        }, {
                "familyName": "Miller",
                "firstName": "Ben"
            }],
        "children": [{
            "familyName": "Merriam",
            "firstName": "Jesse",
            "gender": "female",
            "grade": 8,
            "pets": [{
                "givenName": "Goofy"
            }, {
                    "givenName": "Shadow"
                }]
        }, {
                "familyName": "Miller",
                "firstName": "Lisa",
                "gender": "female",
                "grade": 1
            }],
        "address": {
            "state": "NY",
            "county": "Manhattan",
            "city": "NY"
        },
        "isRegistered": false
    }
};

The database, collection, and document definitions will act as your DocumentDB database id, collection id, and documents' data.

Finally, export your config object, so that you can reference it within the app.js file.

        },
        "isRegistered": false
    }
};

// ADD THIS PART TO YOUR CODE
module.exports = config;

Step 4: Connect to an Azure Cosmos DB account

Open your empty app.js file in the text editor. Copy and paste the code below to import the documentdb module and your newly created config module.

// ADD THIS PART TO YOUR CODE
"use strict";

var documentClient = require("documentdb").DocumentClient;
var config = require("./config");
var url = require('url');

Copy and paste the code to use the previously saved config.endpoint and config.primaryKey to create a new DocumentClient.

var config = require("./config");
var url = require('url');

// ADD THIS PART TO YOUR CODE
var client = new documentClient(config.endpoint, { "masterKey": config.primaryKey });

Now that you have the code to initialize the documentdb client, let's take a look at working with DocumentDB resources.

Step 5: Create a Node database

Copy and paste the code below to set the HTTP status for Not Found, the database url, and the collection url. These urls are how the DocumentDB client will find the right database and collection.

var client = new documentClient(config.endpoint, { "masterKey": config.primaryKey });

// ADD THIS PART TO YOUR CODE
var HttpStatusCodes = { NOTFOUND: 404 };
var databaseUrl = `dbs/${config.database.id}`;
var collectionUrl = `${databaseUrl}/colls/${config.collection.id}`;

A database can be created by using the createDatabase function of the DocumentClient class. A database is the logical container of document storage partitioned across collections.

Copy and paste the getDatabase function for creating your new database in the app.js file with the id specified in the config object. The function will check if the database with the same FamilyRegistry id does not already exist. If it does exist, we'll return that database instead of creating a new one.

var collectionUrl = `${databaseUrl}/colls/${config.collection.id}`;

// ADD THIS PART TO YOUR CODE
function getDatabase() {
    console.log(`Getting database:\n${config.database.id}\n`);

    return new Promise((resolve, reject) => {
        client.readDatabase(databaseUrl, (err, result) => {
            if (err) {
                if (err.code == HttpStatusCodes.NOTFOUND) {
                    client.createDatabase(config.database, (err, created) => {
                        if (err) reject(err)
                        else resolve(created);
                    });
                } else {
                    reject(err);
                }
            } else {
                resolve(result);
            }
        });
    });
}

Copy and paste the code below where you set the getDatabase function to add the helper function exit that will print the exit message and the call to getDatabase function.

            } else {
                resolve(result);
            }
        });
    });
}

// ADD THIS PART TO YOUR CODE
function exit(message) {
    console.log(message);
    console.log('Press any key to exit');
    process.stdin.setRawMode(true);
    process.stdin.resume();
    process.stdin.on('data', process.exit.bind(process, 0));
}

getDatabase()
.then(() => { exit(`Completed successfully`); })
.catch((error) => { exit(`Completed with error ${JSON.stringify(error)}`) });

In your terminal, locate your app.js file and run the command: node app.js

Congratulations! You have successfully created an Azure Cosmos DB database.

Step 6: Create a collection

Warning

CreateDocumentCollectionAsync will create a new collection, which has pricing implications. For more details, please visit our pricing page.

A collection can be created by using the createCollection function of the DocumentClient class. A collection is a container of JSON documents and associated JavaScript application logic.

Copy and paste the getCollection function underneath the getDatabase function in the app.js file to create your new collection with the id specified in the config object. Again, we'll check to make sure a collection with the same FamilyCollection id does not already exist. If it does exist, we'll return that collection instead of creating a new one.

            } else {
                resolve(result);
            }
        });
    });
}

// ADD THIS PART TO YOUR CODE
function getCollection() {
    console.log(`Getting collection:\n${config.collection.id}\n`);

    return new Promise((resolve, reject) => {
        client.readCollection(collectionUrl, (err, result) => {
            if (err) {
                if (err.code == HttpStatusCodes.NOTFOUND) {
                    client.createCollection(databaseUrl, config.collection, { offerThroughput: 400 }, (err, created) => {
                        if (err) reject(err)
                        else resolve(created);
                    });
                } else {
                    reject(err);
                }
            } else {
                resolve(result);
            }
        });
    });
}

Copy and paste the code below the call to getDatabase to execute the getCollection function.

getDatabase()

// ADD THIS PART TO YOUR CODE
.then(() => getCollection())
// ENDS HERE

.then(() => { exit(`Completed successfully`); })
.catch((error) => { exit(`Completed with error ${JSON.stringify(error)}`) });

In your terminal, locate your app.js file and run the command: node app.js

Congratulations! You have successfully created a DocumentDB collection.

Step 7: Create a document

A document can be created by using the createDocument function of the DocumentClient class. Documents are user defined (arbitrary) JSON content. You can now insert a document into DocumentDB.

Copy and paste the getFamilyDocument function underneath the getCollection function for creating the documents containing the JSON data saved in the config object. Again, we'll check to make sure a document with the same id does not already exist.

            } else {
                resolve(result);
            }
        });
    });
}

// ADD THIS PART TO YOUR CODE
function getFamilyDocument(document) {
    let documentUrl = `${collectionUrl}/docs/${document.id}`;
    console.log(`Getting document:\n${document.id}\n`);

    return new Promise((resolve, reject) => {
        client.readDocument(documentUrl, { partitionKey: document.district }, (err, result) => {
            if (err) {
                if (err.code == HttpStatusCodes.NOTFOUND) {
                    client.createDocument(collectionUrl, document, (err, created) => {
                        if (err) reject(err)
                        else resolve(created);
                    });
                } else {
                    reject(err);
                }
            } else {
                resolve(result);
            }
        });
    });
};

Copy and paste the code below the call to getCollection to execute the getFamilyDocument function.

getDatabase()
.then(() => getCollection())

// ADD THIS PART TO YOUR CODE
.then(() => getFamilyDocument(config.documents.Andersen))
.then(() => getFamilyDocument(config.documents.Wakefield))
// ENDS HERE

.then(() => { exit(`Completed successfully`); })
.catch((error) => { exit(`Completed with error ${JSON.stringify(error)}`) });

In your terminal, locate your app.js file and run the command: node app.js

Congratulations! You have successfully created a DocumentDB documents.

Node.js tutorial - Diagram illustrating the hierarchical relationship between the account, the database, the collection, and the documents - Node database

Step 8: Query Azure Cosmos DB resources

Azure Cosmos DB supports rich queries against JSON documents stored in each collection. The following sample code shows a query that you can run against the documents in your collection.

Copy and paste the queryCollection function underneath the getFamilyDocument function in the app.js file. DocumentDB supports SQL-like queries as shown below. For more information on building complex queries, check out the Query Playground and the query documentation.

            } else {
                resolve(result);
            }
        });
    });
}

// ADD THIS PART TO YOUR CODE
function queryCollection() {
    console.log(`Querying collection through index:\n${config.collection.id}`);

    return new Promise((resolve, reject) => {
        client.queryDocuments(
            collectionUrl,
            'SELECT VALUE r.children FROM root r WHERE r.lastName = "Andersen"'
        ).toArray((err, results) => {
            if (err) reject(err)
            else {
                for (var queryResult of results) {
                    let resultString = JSON.stringify(queryResult);
                    console.log(`\tQuery returned ${resultString}`);
                }
                console.log();
                resolve(results);
            }
        });
    });
};

The following diagram illustrates how the DocumentDB SQL query syntax is called against the collection you created.

Node.js tutorial - Diagram illustrating the scope and meaning of the query - Node database

The FROM keyword is optional in the query because DocumentDB queries are already scoped to a single collection. Therefore, "FROM Families f" can be swapped with "FROM root r", or any other variable name you choose. DocumentDB will infer that Families, root, or the variable name you chose, reference the current collection by default.

Copy and paste the code below the call to getFamilyDocument to execute the queryCollection function.

.then(() => getFamilyDocument(config.documents.Andersen))
.then(() => getFamilyDocument(config.documents.Wakefield))

// ADD THIS PART TO YOUR CODE
.then(() => queryCollection())
// ENDS HERE

.then(() => { exit(`Completed successfully`); })
.catch((error) => { exit(`Completed with error ${JSON.stringify(error)}`) });

In your terminal, locate your app.js file and run the command: node app.js

Congratulations! You have successfully queried Azure Cosmos DB documents.

Step 9: Replace a document

Azure Cosmos DB supports replacing JSON documents.

Copy and paste the replaceFamilyDocument function underneath the queryCollection function in the app.js file.

                }
                console.log();
                resolve(result);
            }
        });
    });
}

// ADD THIS PART TO YOUR CODE
function replaceFamilyDocument(document) {
    let documentUrl = `${collectionUrl}/docs/${document.id}`;
    console.log(`Replacing document:\n${document.id}\n`);
    document.children[0].grade = 6;

    return new Promise((resolve, reject) => {
        client.replaceDocument(documentUrl, document, (err, result) => {
            if (err) reject(err);
            else {
                resolve(result);
            }
        });
    });
};

Copy and paste the code below the call to queryCollection to execute the replaceDocument function. Also, add the code to call queryCollection again to verify that the document had successfully changed.

.then(() => getFamilyDocument(config.documents.Andersen))
.then(() => getFamilyDocument(config.documents.Wakefield))
.then(() => queryCollection())

// ADD THIS PART TO YOUR CODE
.then(() => replaceFamilyDocument(config.documents.Andersen))
.then(() => queryCollection())
// ENDS HERE

.then(() => { exit(`Completed successfully`); })
.catch((error) => { exit(`Completed with error ${JSON.stringify(error)}`) });

In your terminal, locate your app.js file and run the command: node app.js

Congratulations! You have successfully replaced an Azure Cosmos DB document.

Step 10: Delete a document

Azure Cosmos DB supports deleting JSON documents.

Copy and paste the deleteFamilyDocument function underneath the replaceFamilyDocument function.

            else {
                resolve(result);
            }
        });
    });
};

// ADD THIS PART TO YOUR CODE
function deleteFamilyDocument(document) {
    let documentUrl = `${collectionUrl}/docs/${document.id}`;
    console.log(`Deleting document:\n${document.id}\n`);

    return new Promise((resolve, reject) => {
        client.deleteDocument(documentUrl, (err, result) => {
            if (err) reject(err);
            else {
                resolve(result);
            }
        });
    });
};

Copy and paste the code below the call to the second queryCollection to execute the deleteDocument function.

.then(() => queryCollection())
.then(() => replaceFamilyDocument(config.documents.Andersen))
.then(() => queryCollection())

// ADD THIS PART TO YOUR CODE
.then(() => deleteFamilyDocument(config.documents.Andersen))
// ENDS HERE

.then(() => { exit(`Completed successfully`); })
.catch((error) => { exit(`Completed with error ${JSON.stringify(error)}`) });

In your terminal, locate your app.js file and run the command: node app.js

Congratulations! You have successfully deleted an Azure Cosmos DB document.

Step 11: Delete the Node database

Deleting the created database will remove the database and all children resources (collections, documents, etc.).

Copy and paste the cleanup function underneath the deleteFamilyDocument function to remove the database and all the children resources.

            else {
                resolve(result);
            }
        });
    });
};

// ADD THIS PART TO YOUR CODE
function cleanup() {
    console.log(`Cleaning up by deleting database ${config.database.id}`);

    return new Promise((resolve, reject) => {
        client.deleteDatabase(databaseUrl, (err) => {
            if (err) reject(err)
            else resolve(null);
        });
    });
}

Copy and paste the code below the call to deleteFamilyDocument to execute the cleanup function.

.then(() => deleteFamilyDocument(config.documents.Andersen))

// ADD THIS PART TO YOUR CODE
.then(() => cleanup())
// ENDS HERE

.then(() => { exit(`Completed successfully`); })
.catch((error) => { exit(`Completed with error ${JSON.stringify(error)}`) });

Step 12: Run your Node.js application all together!

Altogether, the sequence for calling your functions should look like this:

getDatabase()
.then(() => getCollection())
.then(() => getFamilyDocument(config.documents.Andersen))
.then(() => getFamilyDocument(config.documents.Wakefield))
.then(() => queryCollection())
.then(() => replaceFamilyDocument(config.documents.Andersen))
.then(() => queryCollection())
.then(() => deleteFamilyDocument(config.documents.Andersen))
.then(() => cleanup())
.then(() => { exit(`Completed successfully`); })
.catch((error) => { exit(`Completed with error ${JSON.stringify(error)}`) });

In your terminal, locate your app.js file and run the command: node app.js

You should see the output of your get started app. The output should match the example text below.

Getting database:
FamilyDB

Getting collection:
FamilyColl

Getting document:
Anderson.1

Getting document:
Wakefield.7

Querying collection through index:
FamilyColl
    Query returned [{"firstName":"Henriette Thaulow","gender":"female","grade":5,"pets":[{"givenName":"Fluffy"}]}]

Replacing document:
Anderson.1

Querying collection through index:
FamilyColl
    Query returned [{"firstName":"Henriette Thaulow","gender":"female","grade":6,"pets":[{"givenName":"Fluffy"}]}]

Deleting document:
Anderson.1

Cleaning up by deleting database FamilyDB
Completed successfully
Press any key to exit

Congratulations! You've created you've completed the Node.js tutorial and have your first Azure Cosmos DB console application!

Get the complete Node.js tutorial solution

If you didn't have time to complete the steps in this tutorial, or just want to download the code, you can get it from GitHub.

To run the GetStarted solution that contains all the samples in this article, you will need the following:

Install the documentdb module via npm. Use the following command:

  • npm install documentdb --save

Next, in the config.js file, update the config.endpoint and config.authKey values as described in Step 3: Set your app's configurations.

Then in your terminal, locate your app.js file and run the command: node app.js.

That's it, build it and you're on your way!

Next steps