MongoDB is a NoSQL database that stores data in flexible, JSON like documents which means that fields can vary from document to document and data structure can be changed over time.
In our modern world data is vast, unstructured, and sometimes unwieldy. It can get big and complicated very fast which can make it hard to store it in databases with a fixed table structure.
Most projects require a more flexible solution and that’s where MongoDB comes into place. Its flexible JSON like documents provide an easy and logical way to store data and enable us developers to easily change our data structures over time.
In this post, we will go over the important concepts of MongoDB and take a look at how it can help us developers deliver better products and improve our development experience.
Table of contents
Open Table of contents
SQL vs NoSQL
Before diving into why we should choose MongoDB over other databases, you should first have a clear understanding of the differences between SQL and NoSQL databases.
Structure
SQL databases use structured query language for defining and manipulating their data. They are table based which makes them very powerful and a great choice for complex queries but on the other hand, can also be very restrictive. SQL requires the use of pre-defined schemas to determine the structure of our data which can make it hard to change and maintain the data structure over time.
NoSQL on the other hand has dynamic schemas of unstructured data and is either document, key-value or graph-oriented. This means that documents can be created without needing to define a schema first and that each document can have its own unique structure. It also provides the possibility to easily add fields as you go without having to worry about the data schema.
When to use which
SQL is a strong choice for any project that will benefit from its predefined data structure and set schemas. It is also useful if all data must have the same structure without room for error.
NoSQL is a great choice for projects with no clear schema definitions or companies experiencing rapid growth. NoSQL provides much more flexibility which also makes it a great option for projects with many different data models.
Now that we know the key differences between SQL and NoSQL databases let’s move on to why we should use MongoDB of all the databases out there.
Note: I just gave a quick overview of the most important differences between SQL and NoSQL databases.
Why care about MongoDB
Now the question remains why you should use MongoDB in the first place. Here are some reasons developers should consider learning and using MongoDB.
Here are some of the great benefits MongoDB provides:
- Schemaless (Document oriented which means that documents can differ from one another)
- Helps you handle large amounts of unstructured data
- Easy to scale
- Rich queries
- Index on any attribute
- Professional support
When should you use it
By now we should know why MongoDB is useful and where it can improve our applications and development experience. But it’s not the best solution for every project so let’s take a look at where you should definitely use MongoDB.
- When you store schema-less data
- When you have an application that often adds fields of data
- When you need flexible data storage
- When you want to horizontally scale your hosting
Setup
To set up MongoDB, we just need to download the installer and execute it. If you need any help installing MongoDB I can only recommend visiting the official documentation or this blog post by London App Brewery about installing MongoDB on Windows.
After installing it we can take a look at how we can use it in our projects and the basic CRUD functionality.
Basic Server
Before we can start taking a look at how we can implement CRUD functionality into our app we first need to create a basic MongoDB server.
For that, we first need to install the MongoDB dependency in our project and can do so using the npm package manager.
npm install mongodb --save
Connecting to MongoDB
First, we need to require the mongodb
package we just installed and get the MongoClient
object from it.
const mongo = require('mongodb').MongoClient
After that, we need to create a URL to the MongoDB server. If you use it locally like I’m doing in this blogpost the URL will be looking something like mongodb://localhost:27017
.
const url = 'mongodb://localhost:27017'
We also need to define the name of our database:
const dbName = 'exampleproject'
Then we need to use the mongo.connect()
function to get reference to our MongoDB client.
mongo.connect(url, (err, client) => {
if (err) {
console.error(err)
return
}
console.log('Connected successfully to server')
const db = client.db(dbName)
})
Now that we have the basic structure down let’s look at how we can implement CRUD functionality into our app.
CRUD functionality
Now let’s look at how we can implement the basic CRUD (Create, Read, Update, Delete) functionality.
For that we first need to create or get a collection of our database in which we will work in. We can do so using the collection()
function which takes the collection name as an argument.
const collection = db.collection('collectionname')
Create
We can insert an object into our database using the insertOne()
function provided by MongoDB.
collection.insertOne({ name: 'Test', age: '30' }, ((error, item) => {
if(error) {
console.error(error)
return
}
console.log(item)
}))
We can also insert multiple items using the insertMany()
function.
collection.insertMany([{name: 'Test', age: '30'}, {name: 'Test2', age: '60'}], (error, result) => {
})
Read
The find()
function is used to get all documents of a collection.
collection.find().toArray((error, items) => {
console.log(items)
})
We can also pass an argument to the find()
function to only get specific documents.
collection.find({name: 'Gabriel'}).toArray((error, items) => {
console.log(items)
})
If we just want to get one element we can skip the toArray function using findOne()
.
collection.findOne({name: 'Gabriel'}, (error, item) => {
console.log(item)
})
Update
Next up let’s look how we can update an already existing document using the updateOne()
function.
collection.updateOne({name: 'Gabriel'}, {'$set': {'name': 'Jeff'}}, (error, item) => {
console.log(item)
})
We can also update multiple documents using the updateMany()
function instead.
collection.updateMany({ name: 'Gabriel' },{'$set': {'name': 'Jeff'} }, (error, item) => {
console.log(item)
})
Delete
Now let’s look at how we can delete documents in our database.
collection.deleteMany({name: 'Gabriel'}, (error, item) => {
console.log(item)
})
Use the deleteOne()
function if you want to delete only one document.
collection.deleteOne({name: 'Gabriel'}, (error, item) => {
console.log(item)
})
Schema Design
Schema design is a very important part of MongoDB and can help us developers build more robust and fast applications.
Common benefits of using schema design include:
- Fewer writes to the database
- Simpler and faster queries
- Design simplification when the document structure is known in advance
- Reduced future technical debt
How do we design a schema
Before we can start looking at the different schemas we need to ask ourselves some questions about our data and data structure. These are the most important:
- Your data access patterns
- Number of reads vs updates
- Size of the documents
- Data & Index Size
- Scalability
If you want to know more about Mongo schema patterns you can look at this official video from the MongoDB team.
Now that we know the important parts of MongoDB schema design let’s look at how we can implement schemas in our Nodejs applications.
Mongoose
Another awesome feature that is often used next to Mongo itself is Mongoose which provides a straight-forward, schema-based solution to model your application data and makes validation and casting easier.
Installing Mongoose
Mongoose can be installed using the npm or yarn package manager either globally or just for one project.
npm install mongoose --save
Connecting to MongoDB
After installing the mongoose dependency in your project you can continue by instantiating a connection to your MongoDB database.
const mongoose = require('mongoose');
mongoose.connect('mongodb://localhost/test', {useNewUrlParser: true});
You can also add some basic logging so you know your connection established correctly or the error that occurred.
mongoose
.connect(
`mongodb://localhost/test`, {
useNewUrlParser: true
}
)
.then(() => console.log('MongoDB Connected'))
.catch(err => console.log(err))
Creating a schema
Mongoose now enables us to create a predefined schema for our database object like you would do with traditional SQL databases. A schema maps to a MongoDB collection and defines the shape of the documents within that collection.
const userSchema = mongoose.Schema({
email: {
type: String,
require: true,
unique: true
},
password: {
type: String,
require: true
},
})
Each key in our mongoose.Schema()
defines a property in our documents that will be cast to its associated SchemaType
we define.
You can take a look at the official documentation for a more detailed look at schemas.
Create a model
Now that we have a finished schema at our disposal we can continue compiling it into a model.
const user = mongoose.model('User', userSchema)
A model is a class that is used to construct specific documents as you will see in the next step.
Saving an item
Our model now allows us to create a specific document that we can use in our database operations.
const user = new User({
email: "[email protected]",
password: "password123",
})
After creating the document we can save it using the save()
function.
user.save().then(() => {
console.log("Successfully saved document)
}).catch((error) => {
console.log(error)
})
Finding an item
Finding an item is also a completely simple process that can be done using a single command.
The find()
method finds all objects in the given collection that match the query you passed it.
// Request with no query
const users = await user.find()
//Request with a specific query
const specificUser = await user.find({email: "[email protected]"})
If you only want to find a single item I would recommend using the findOne()
method instead.
Mongo Atlas
MongoDB Atlas is a global cloud database service that allows you to deploy and manage MongoDB applications in a Cluster across AWS, Azure, or GCP.
Why should you use Atlas
Here is a list of reasons why you should use Atlas and where it can help you in your workflow:
- Quick and simple - Atlas doesn’t require any installation or config file. Just signup create your cluster and you are all set
- Cloud database - No need for a MongoDB installation on your machine. The cloud also helps when running your application in container clusters like Kubernetes
- Secure for sensitive data - Atlas has built-in security controls for all your data
- Great free tier up to 512MB of Storage
I will not go over MongoDB Atlas further in this article. If you want to learn how to set up a cluster and connect your application to it, I would recommend using the official documentation or this guide by Lenmor Ld.
Conclusion
You made it all the way until the end! I hope that this article helped you understand the basics of MongoDB and how you can use it in Javascript.
If you have found this useful, please consider recommending and sharing it with other fellow developers. If you have any questions or feedback, let me know using my contact form or contact me on Twitter.