One of the really powerful things about a document database like MongoDB is the ability to store arrays of values in a document. Arrays can even store sub-documents, allowing for many levels of nested data.
An example use case of an array in a document database is a user with multiple addresses. In a relational database, this address information would be stored in a separate table. To get a users addresses, the addresses table would be joined with the users table. In MongoDB, a user and their addresses can be stored in one document, making data access and updates quick and easy (with no expensive
Now let's look at some array operations in the MongoDB shell. I created a document called
user which holds running log information. This info consists of an array of exercise logs, an array of planned exercises, and the users personal records.
Accessing data from nested objects and arrays is easy. For example, each user has a
plan array that contains exercise plans. Each item in the
plan array contains two properties - a date and a distance in miles. If I'm only interested in the miles and not the date, I can use the following dot notation -
If I only want the first item in the
plan array, I can use the
$slice determines the number of items to return from an array.
$slice is given a value of 1 which returns the first element in the array. If
$slice is given a negative value it returns items from the end of the array.
Indexes are easily added to nested properties using dot notation:
There are numerous operators for updating arrays, including
$pop removes an item from an array, while both
$addToSet add an item to an array. With
$addToSet, a new item is only added if it does not already exist in the array. This is a better option if duplicates should be avoided.
One important operator for updating in MongoDB is
findAndModify(). This command both updates and returns the newly altered document atomically1. All updates in MongoDB are performed atomically (an update is never half completed and no database connection ever sees an update in progress). However, when calling the
find() operations separately, there is a chance that another update is performed in between the execution of both commands.
findAndModify() eliminates this problem so you know any changes reflected in the document are from the update just performed. The following query adds another sub-document to the plan array and also returns the newly updated document.
These code samples begin to expose the power of arrays and sub-documents in MongoDB. A multi-table RDBMS structure is easily compressed into a single document with MongoDB. All the code samples from this post are on GitHub.