Introduction to MongoDB
MongoDB is a document database: it stores data as JSON-like documents instead of rows in tables. Start a database, save three products of different shapes, find them again with mongosh, and read the same data from a Node.js program.
What you will be able to do
- Explain in simple words what MongoDB is and what a document database stores
- Name the three levels: database, collection, document
- Save documents with insertOne() and read them with find() and findOne()
- Search with a simple filter, including a field inside a nested object
- Explain how an application talks to MongoDB through a driver
The idea, in plain English
Most programs need to remember things: users, products, orders, messages. A database is a program whose job is to store this data safely and find it again quickly. MongoDB is one of the most popular databases.
Many databases store data in tables, like a spreadsheet: every row has the same columns. MongoDB stores data as documents instead. A document looks like a JavaScript object or JSON: { name: "Desk lamp", price: 24.5 }. A document can hold lists and other documents inside it, and two documents in the same place can have different fields. This is why MongoDB is called a document database.
In this lesson we start MongoDB, save a few products, and find them again - first with mongosh, the MongoDB shell, and then from a small Node.js program. Everything was run on MongoDB 9.0.2 with mongosh 2.3 and the Node.js driver 7.7. Lesson 1.7 shows how to install MongoDB yourself; until then you can read along, or use a free Atlas cluster (Lesson 1.8).
Worked example: A small shop: three products with different fields - one with tags, one with pages, one with a nested specs object - saved and searched in mongosh, then read from Node.js.
1 - Connect
Your program - the mongosh shell or a Node.js app - connects to the MongoDB server over the network.
A MongoDB server holds databases, a database holds collections, a collection holds documents. Real names from our example.
Words you will see in this lesson
A few words you will meet in every MongoDB lesson.
DatabaseA program that stores data and finds it again. Also: one named group of collections, like "shop".DocumentOne record, written like a JSON object: { name: "Pen", price: 2 }.FieldOne name-value pair inside a document: price: 2.CollectionA group of documents, like "products". Similar to a table in SQL.mongodThe MongoDB server program that stores the data.mongoshThe MongoDB shell: you type commands, it shows results.DriverA library that lets your program (Node.js, Python...) talk to MongoDB._idA unique id that every document has. MongoDB adds one if you do not.An everyday example: a filing cabinet
Think of an office filing cabinet. The cabinet is the database. Each drawer is a collection: one drawer for customers, one for invoices. Each drawer holds folders - the documents. One folder holds everything about one customer: name, address, phone numbers, notes. You do not split one customer across five drawers.
Folders in the same drawer do not need the same pages. One customer has two phone numbers, another has none. That is how MongoDB works: each document holds everything about one thing, and documents can differ.
Example 1 - your first documents
We wrote the commands in a file and ran it with mongosh first.js. use("shop") chooses the database "shop". It did not exist yet - MongoDB creates it when the first document is saved.
db.products is the collection "products" in the current database. insertOne() saves one document. Look at the three products: the lamp has tags (a list), the notebook has pages, the headphones have specs (a document inside the document). MongoDB accepted all three in the same collection.
find() returns all documents in the collection. find({ price: { $lt: 30 } }) returns only the ones whose price is less than ($lt) 30. The second part, { _id: 0, name: 1, price: 1 }, says which fields to show - Lesson 2.6 explains it. "specs.wireless" with a dot looks inside the specs object.
// Lesson 1.1 - first steps in mongosh
use("shop") // switch to (or start) the "shop" database
db.products.insertOne({ name: "Desk lamp", price: 24.5, tags: ["home", "light"] })
db.products.insertOne({ name: "Notebook", price: 3, pages: 120 }) // a different shape - allowed
db.products.insertOne({
name: "Headphones",
price: 59,
specs: { wireless: true, batteryHours: 30 }, // a document inside a document
})
print("--- all products")
printjson(db.products.find().toArray())
print("--- cheaper than 30")
printjson(db.products.find({ price: { $lt: 30 } }, { _id: 0, name: 1, price: 1 }).toArray())
print("--- wireless ones")
printjson(db.products.find({ "specs.wireless": true }, { _id: 0, name: 1 }).toArray())
print("--- how many:", db.products.countDocuments())
print("--- databases:")
printjson(db.adminCommand({ listDatabases: 1, nameOnly: true }).databases.map(d => d.name))--- all products
[
{
_id: ObjectId('6acaf5a4af90302d773ca77e'),
name: 'Desk lamp',
price: 24.5,
tags: [
'home',
'light'
]
},
{
_id: ObjectId('6acaf5a4af90302d773ca77f'),
name: 'Notebook',
price: 3,
pages: 120
},
{
_id: ObjectId('6acaf5a4af90302d773ca780'),
name: 'Headphones',
price: 59,
specs: {
wireless: true,
batteryHours: 30
}
}
]
--- cheaper than 30
[
{
name: 'Desk lamp',
price: 24.5
},
{
name: 'Notebook',
price: 3
}
]
--- wireless ones
[
{
name: 'Headphones'
}
]
--- how many: 3
--- databases:
[
'admin',
'config',
'library',
'limits13',
'local',
'shop',
'shop12'
]Tip: Your _id values will be different - MongoDB creates a new one for every document. Lesson 1.12 explains what is inside an ObjectId.
Reading the output
Every document came back with an _id field we never wrote: ObjectId('6acaf5a4...'). MongoDB adds a unique _id to every document that does not have one. It is how MongoDB tells two documents apart.
The documents came back exactly as we saved them, with their different fields. Nothing was converted into columns. The database list shows "shop" next to three databases MongoDB uses for itself: admin, config and local.
Example 2 - typing commands one by one
You can also open mongosh and type commands one at a time. The prompt shows the current database (test> at the start). "show dbs" lists databases, "show collections" lists collections. Look at the first "show dbs": "library" is not there yet. After the first insertOne, it is.
insertOne() answers with acknowledged: true (the server confirmed the write) and the insertedId - the _id of the new document. findOne() returns the first matching document, not a list.
test> use library
switched to db library
library> show dbs
admin 8.00 KiB
config 12.00 KiB
local 8.00 KiB
shop 8.00 KiB
library> db.books.insertOne({ title: "Wings of Fire", author: "A. P. J. Abdul Kalam", year: 1999 })
{
acknowledged: true,
insertedId: ObjectId('6acaf44868fbe28a106a54b7')
}
library> show dbs
admin 8.00 KiB
config 12.00 KiB
library 8.00 KiB
local 8.00 KiB
shop 8.00 KiB
library> show collections
books
library> db.books.findOne()
{
_id: ObjectId('6acaf44868fbe28a106a54b7'),
title: 'Wings of Fire',
author: 'A. P. J. Abdul Kalam',
year: 1999
}Example 3 - the same data from Node.js
mongosh is for you, the developer. Your application talks to MongoDB through a driver - a library for its language. This course uses the official Node.js driver (npm install mongodb). Module 5 covers it in detail; here is a first look.
MongoClient gets the address of the server - a connection string (Lesson 5.2). client.db("shop").collection("products") is the same database and collection as before. find() takes the same filter, and the field choice goes into { projection: ... }. await waits for the answer, because talking to a database takes time.
// Lesson 1.1 - the same data, from a Node.js program
import { MongoClient } from "mongodb";
const client = new MongoClient("mongodb://127.0.0.1:27017"); // where MongoDB runs
await client.connect();
const products = client.db("shop").collection("products"); // database -> collection
const cheap = await products
.find({ price: { $lt: 30 } }, { projection: { _id: 0, name: 1, price: 1 } })
.toArray();
console.log(cheap);
await client.close();[ { name: 'Desk lamp', price: 24.5 }, { name: 'Notebook', price: 3 } ]Why developers choose MongoDB
Documents look like the objects in your code. A product in JavaScript is an object with a list of tags and a nested specs object - MongoDB stores it the same way. There is less translating between your code and your database.
Fields can change over time. When the shop starts selling books with an "isbn" field, you just save books with that field. Lesson 1.2 compares this with SQL, and Lesson 1.3 shows the other side: what this freedom costs.
MongoDB is also built to grow: copies of the data on several servers (Module 7, replication) and data split across servers (sharding). You do not need these on day one, but they are there.
First commands
Choose a databaseCreated on first save.
use("shop") // or: use shopSave one documentAdds _id if missing.
db.products.insertOne({ name: "Pen", price: 2 })Find allEvery document.
db.products.find()
Find with a filterPrice below 30.
db.products.find({ price: { $lt: 30 } })Inside an objectDot notation.
db.products.find({ "specs.wireless": true })Find oneA document, not a list.
db.books.findOne()
CountNumber of documents.
db.products.countDocuments()
ListDatabases, collections.
show dbs show collections
Try it yourself
The code does not change. Swap the content string and the program does something else entirely.
“Insert a product with a field no other product has, like color: "blue". Then find it with { color: "blue" }.”
“Find products whose price is greater than 20. Hint: $gt instead of $lt.”
“Find products whose specs.batteryHours is at least 20 ($gte).”
“Run db.products.find({ price: 1000 }). What does an empty result look like?”
What usually goes wrong
"show dbs" did not list "library" until the first document was saved. An empty database is not stored.
A field path with a dot must be a string.
✗ db.products.find({ specs.wireless: true })✓ db.products.find({ "specs.wireless": true })MongoDB accepts any shape, but your app still needs consistent data. Lesson 1.3 shows a typo that silently hid a product; Module 2 shows how to design and validate documents.
Practice
Write these yourself before opening anything. Getting them wrong first is most of how this sticks.
Create a database "school" with a collection "students". Insert three students with name, age and a list of subjects; give one of them an extra field "monitor: true". Then find all students older than 15, and find the monitor.
Show hintHide hint
use("school"), db.students.insertOne({...}) three times, db.students.find({ age: { $gt: 15 } }), db.students.find({ monitor: true }).
Key points
- MongoDB is a document database: it stores JSON-like documents, not table rows.
- A server holds databases; a database holds collections; a collection holds documents.
- Documents in one collection can have different fields, lists and nested documents.
- Every document has a unique _id; MongoDB adds an ObjectId if you do not.
- insertOne() saves, find() returns matching documents, findOne() returns one.
- You use mongosh; your application uses a driver, like the Node.js driver.
Quick check before you move on
Interview questions
What is MongoDB?
A general-purpose, document-oriented NoSQL database that stores data as BSON documents in collections, with a flexible schema, rich queries and aggregation, secondary indexes, and built-in replication and sharding.
How does MongoDB organise data compared with a relational database?
Database to database, collection to table, document to row, field to column - but documents can nest objects and arrays and do not have to share one fixed set of columns.
Why can a document model reduce work for application developers?
Documents map naturally to objects in code, related data can be stored together and read in one query, and new fields can be added without a schema migration.
Quiz
- 1.
Could the Notebook have "pages" while the Desk lamp had "tags", in the same collection?
- 2.
What is the difference between find() and findOne()?
- 3.
What did insertOne() answer?
- 4.
What is a driver?
Comments
Sign in to leave a comment. Your name and photo come from Google; nothing else is shared.
Loading comments...