Database
Intermediate 15 min read Database

NoSQL & Document Stores

Document stores like MongoDB keep self-contained JSON records and trade joins for denormalization. Understand the CAP theorem, embedding vs referencing, sharding, and when NoSQL beats a relational database.

NoSQLMongoDBdocument storeCAP theoremshardingdenormalizationaggregation
Introduction

What is this?

NoSQL is an umbrella term for databases that abandon the relational model for other shapes: key-value (Redis), wide-column (Cassandra, Bigtable), document (MongoDB) and graph (Neo4j). Document stores keep self-contained records as JSON-like documents and use the CAP theorem to reason about consistency, availability and partition tolerance. They shine when the write path, flexible schema or horizontal scale matters more than cross-record joins.

Motivation

Why do you need it?

  • A document holds a whole aggregate — order, customer and items — so one read replaces a multi-table join.
  • Schemas are flexible: fields can vary per document, easing early-stage product churn.
  • Horizontal scaling is a first-class goal, with data sharded across many nodes from day one.
  • Some workloads — caches, sessions, leaderboards, event streams — fit a key or document model far better than SQL.
  • Operational simplicity: replication and sharding are built in rather than bolted on.
Think about it

Mental model

Imagine

A packed suitcase for one trip

Think of

A document in MongoDB

You grab one bag instead of assembling pieces from several closets. But pack the same shirt into two suitcases and you must remember to update both — that is the denormalization cost.

Mechanics

How it works

  • A document store serializes each record as BSON/JSON with a unique _id.
  • The shard key routes each write to a specific shard, keeping related data together.
  • Reads on _id hit the owning shard directly; queries on other fields use secondary indexes.
  • Replication copies the oplog to replica-set members for durability and read scaling.
  • Consistency is configurable: a write can be acknowledged by one node, a majority, or all nodes.
  • Atomic operators like $set and $push modify embedded fields inside a single document atomically.

Relational join versus embedded document.

orders + customers tables
JOIN at read time
Embedded order document
Single document read
Update fan-out
Read speed vs write cost
Reference

Key commands

mongosh mongodb://localhost:27017/shop

Connect to a MongoDB server and the shop database.

db.orders.insertOne({ customer_id: 1, total: 42 })

Insert a single document into a collection.

db.orders.find({ status: 'paid' }).limit(10)

Query documents with a filter and a limit.

db.orders.createIndex({ customer_id: 1 })

Create an index on customer_id for faster lookups.

db.orders.updateOne({ _id: 1 }, { $set: { status: 'shipped' } })

Atomically set a field on one document.

db.orders.aggregate([{ $match: { status: 'paid' } }, { $group: { _id: '$customer_id', total: { $sum: '$total' } } }])

Aggregate paid orders per customer with the aggregation pipeline.

Hands-on

Examples

Inserting an order document

Inserting an order document
db.orders.insertOne({
_id: ObjectId("64a1b2c3d4e5f6a7b8c9d0e1"),
customer: { name: "Ada Lovelace", email: "ada@example.com" },
items: [
{ sku: "LAP-001", name: "ThinkPad", price: 1299.00, qty: 1 },
{ sku: "USB-004", name: "USB-C Dock", price: 89.00, qty: 2 }
],
total: 1477.00,
status: "pending",
createdAt: new Date()
});

The whole order — customer snapshot, line items and totals — is one document in the orders collection. A page that shows an order reads one document instead of joining three tables. The trade-off: changing the customer's email requires updating every order that embedded it.

Real world

In production

  • Content and catalog systems store rich, variable-shaped documents (articles, products, media) as documents.
  • Session stores and caches use key-value databases for sub-millisecond reads.
  • IoT telemetry writes millions of small records into wide-column stores optimized for append-heavy loads.
  • Fraud and recommendation engines use graph databases to traverse relationships like friend-of-friend.
Guidelines

Best practices

  • Model for your queries: shape documents around the reads you will issue, not the other way around.
  • Keep aggregates denormalized but bounded — do not embed a thousand-element array in one document.
  • Use secondary and compound indexes exactly as you would in SQL for hot filters.
  • Choose write concerns and read preferences deliberately; 'majority' trades latency for safety.
  • Cap embedded arrays and split hot aggregates so documents do not grow without bound.
Watch out

Common mistakes

  • Embedding data that changes in many places, then paying multi-document consistency costs on every update.
  • Expecting multi-document transactions to be free — they work but are slower and best avoided on hot paths.
  • Sharding with a low-cardinality or monotonically increasing shard key, creating hot spots on one node.
  • Believing 'schema-less' means no schema discipline — you still need validation and evolution.
Root cause analysis

Common issues

Error
BSONObj size: 16777228 ... must be between 0 and 16793600
Root cause

A document exceeds MongoDB's 16MB limit.

Fix

Split embedded arrays into a separate collection or store large blobs in an object store.

Error
Cannot create index ... conflicts with shard key
Root cause

The index does not start with the shard key prefix.

Fix

Include the shard key as the leading field of the index.

Error
WriteConcernError: 'majority' write concern not satisfied
Root cause

The replica set cannot meet the requested write concern.

Fix

Configure the write concern on the replica set, or lower it for this operation.

When things break

Debugging tips

  • Run explain('executionStats') to see whether a query used an index or a collection scan.
  • Check db.currentOp() for long-running or stuck operations.
  • Watch mongostat or Atlas metrics for queueing, which points to hot shards or missing indexes.
  • Inspect document sizes — the 16MB BSON limit and oversized payloads are common surprises.
Interviews

Interview checkpoint

Practice

Hands-on lab

Modeling an E-Commerce Store
30 min · intermediate
In progress
Objectives
  • Insert and query documents in MongoDB
  • Model an order as an embedded aggregate
  • Build an aggregation pipeline
  • Create indexes and measure query performance

Modeling an E-Commerce Store

30 min · intermediate

0/5 steps
0%
sandbox · Linux sandbox
$
Try these commands
Test yourself

Quick quiz

0/3
1

Which unit of data is the natural home for an order plus its line items in a document store?

2

Document databases provide no consistency guarantees at all.

3

Orders embed customer email and 20% of customers change their email monthly. What is the best design?

Quick reference

Cheat sheet

CRUD in mongosh
db.coll.insertOne(doc)Insert one document
db.coll.find({ ... })Query documents
db.coll.updateOne(f, { $set: ... })Atomic field update
db.coll.deleteOne(f)Remove one document
db.coll.aggregate([...])Pipeline aggregations
Modeling signals
EmbedOne-to-few, read together
ReferenceOne-to-many, changes often
DenormalizeRead-heavy, duplicates ok
Shard keyHigh cardinality, even spread
Write concern1, majority, or all nodes
Go deeper

Official documentation