What MongoDB is and when to use it
MongoDB stores data as documents: JSON-like records with nested objects and arrays. This lesson explains the model, how it differs from relational databases, and where it fits.
- Describe documents, collections and databases
- Explain how BSON relates to JSON
- List the workloads where MongoDB is a strong or weak fit
- Run your first commands in the shell
conceptThe concept
MongoDB is a general-purpose document database. A document is a set of field/value pairs, where values can be scalars, nested documents or arrays. Documents live in collections, and collections live in databases. A deployment is normally a replica set (three or more copies of the data) and can be sharded to scale horizontally.
Open the interactive lesson to use this diagram.
| Relational | MongoDB |
|---|---|
| Database | Database |
| Table | Collection |
| Row | Document |
| Column | Field (can be nested or an array) |
| Primary key | _id field (required, unique per collection) |
| JOIN | Embedding, or $lookup in aggregation |
| Foreign key constraint | None enforced by the server; modelled in the application |
Documents are stored as BSON (binary JSON). BSON adds types JSON lacks (dates, 32/64-bit integers, Decimal128, ObjectId, binary) and length prefixes that make documents fast to traverse.
whyWhy it matters
The document model maps directly onto objects in application code, so a single read can return everything a screen needs. That removes most joins from the hot path and lets the schema evolve without migrations that lock tables. Replication and automatic failover are built in, and sharding spreads both data and write load across machines.
Use caseReal-world scenario
An online shop stores each order with its line items, payment and shipping details embedded. The order page loads with one indexed read. The product catalog stores electronics, books and groceries in one products collection even though each category has different attributes. Analytics run as aggregation pipelines on a secondary so they do not slow down checkout.
Try itExamples
Run and edit these in the interactive lesson.
show dbs
use shop
show collectionsdb.orders.countDocuments()
db.customers.findOne()
db.orders.findOne({}, { orderNo: 1, status: 1, items: 1 })db.products.find({ category: "books" }, { name: 1, attributes: 1 }).limit(2)
db.products.find({ category: "electronics" }, { name: 1, attributes: 1 }).limit(2)internalsUnder the hood
A mongod process hosts databases. Each collection and each index is a separate table in the WiredTiger storage engine, stored as a B-tree in its own file. Documents are kept in BSON, compressed on disk (snappy by default), and decompressed in the WiredTiger cache. Every write on the primary also records an entry in the oplog, which secondaries replay to stay in sync. You will dig into each of these in levels 4 to 6.
Avoid / preferDo this, not that
db.orders.insertOne({ _id: 1001, customerId: 66 })
db.order_items.insertMany([
{ orderId: 1001, productId: "P016", qty: 1 },
{ orderId: 1001, productId: "P078", qty: 2 }
])db.orders.insertOne({
_id: 1001, customerId: 66,
items: [
{ productId: "P016", qty: 1, price: 681.5 },
{ productId: "P078", qty: 2, price: 17.02 }
]
})Copying a relational schema table for table gives you joins on every page view without a relational optimizer. Store together what the application reads together.
mongod --dbpath /data/db # one server in production
mongod --replSet rs0 --dbpath /data/db # three members: one primary and two secondaries
A standalone has no automatic failover, cannot run multi-document transactions and cannot serve change streams. A three-member replica set is the smallest production deployment.
PitfallsCommon mistakes
- Assuming "schemaless" means "no schema design". You still design for access patterns; the schema simply lives in your application and, ideally, in a validator.
- Normalizing everything into many collections and joining with
$lookupeverywhere, which recreates a relational design without the relational optimizer. - Running a single
mongodin production. Use a replica set so you get failover and can take backups from a secondary.
LimitsWhen not to use it
MongoDB is a poor fit when the data is deeply relational and queried in unpredictable ways: many-to-many joins across a dozen entities, ad-hoc reporting that joins everything with everything, or rules that need foreign keys enforced by the database. It is also not a columnar warehouse for scanning billions of rows per query, and not a cache. Use it where the application's access patterns are known and map naturally onto documents.
SecuritySecurity notes
Since 3.6 mongod binds to localhost by default, and that default exists for a reason: tens of thousands of instances exposed on port 27017 without authentication have been wiped and ransomed. Never open the port to the internet, and always run with security.authorization: enabled.
ChallengeTry it yourself
In one expression, list every collection in shop with its document count.
Show one solution
db.getCollectionNames().map(c => ({ collection: c, docs: db.getCollection(c).countDocuments() }))InterviewQuestions you should be able to answer
How is MongoDB different from a relational database?
It stores documents (nested objects and arrays) instead of rows in fixed tables. Data accessed together is usually embedded together, so joins are rarer. Schemas are flexible but can be enforced with $jsonSchema validators. Scaling out is native through sharding, and high availability through replica sets. It supports ACID transactions: single-document always, multi-document since 4.0 (replica sets) and 4.2 (sharded).
What is BSON and why not store plain JSON?
BSON is a binary encoding of JSON-like documents. It adds types (Date, ObjectId, Int32, Int64, Decimal128, binary) and length prefixes so the server can skip over fields without parsing them. JSON has only one number type and no date type, which is not enough for a database.
QuizCheck your understanding
4 questions with instant feedback in the interactive lesson; a wrong answer goes into your review deck.