Intermediate · NoSQL, ORMs and data features · topic 27 of 54 · 30 min
NoSQL and MongoDB
Explanation
What "NoSQL" means
NoSQL means "not only SQL". It is a family of databases that do not store data as tables with fixed columns. Each kind stores data in its own way: documents, key-value pairs, wide columns or graphs.
MongoDB is a document database. A document is one record written like a JSON object: keys and values, with lists and objects inside. A collection is a group of documents, much like a table is a group of rows. MongoDB saves documents in BSON, a binary form of JSON that also knows about dates and exact numbers.
{
"_id": "66f1c0a2e4b0a1b2c3d4e5f6",
"name": "Redmi 13",
"brand": "Redmi",
"category": "phone",
"price": 11999,
"specs": { "ram": "6 GB", "storage": "128 GB" },
"colours": ["black", "blue"]
}Querying MongoDB
You query MongoDB by passing a filter object. A plain value means "equals". Operators start with a dollar sign: $gt means greater than, $lt less than, $in "one of this list". To change a document you use $set, which updates only the fields you name.
// Example only (mongosh or the Node.js driver). It needs a MongoDB server.
db.products.find({ category: 'phone' }); // equality
db.products.find({ price: { $gt: 20000 } }); // price > 20000
db.products.find({ brand: { $in: ['Samsung', 'Redmi'] } }); // one of a list
db.products.insertOne({ name: 'Redmi 13', category: 'phone', price: 11999 });
// Change only the price; other fields stay as they are
db.products.updateOne({ name: 'Redmi 13' }, { $set: { price: 10999 } });| SQL word | MongoDB word |
|---|---|
| Table | Collection |
| Row | Document |
| Column | Field |
| SELECT ... WHERE | find(filter) |
| INSERT | insertOne / insertMany |
| UPDATE ... SET | updateOne(filter, { $set: ... }) |
| JOIN | Embedding, or $lookup in an aggregation |
Embedding vs referencing
Embedding means putting related data inside the same document, for example the items of an order inside the order. Referencing means storing only an id, such as customerId, and fetching the customer separately, like a foreign key in SQL.
- Embed when the data is always read together, belongs to one parent and stays small (order items, an address).
- Reference when the data is shared by many documents (a customer with hundreds of orders) or keeps growing without limit (comments on a viral post).
- Reference when the data changes on its own often; otherwise you must update many copies.
- A single MongoDB document can be at most 16 MB, so lists that grow forever must not be embedded.
When NoSQL fits, and when SQL is better
| Situation | Usually better |
|---|---|
| Money, bookings, stock counts (need strict transactions and constraints) | SQL (PostgreSQL, MySQL) |
| Data with many links between tables, lots of reports | SQL |
| Records with very different shapes (product catalogue with varied specs) | Document database, or SQL with a JSON column |
| Huge write volume, simple lookups by key (sensor data, event logs) | Wide-column or key-value store |
| Fast cache, sessions, counters | Key-value (Redis) |
| Friends-of-friends, recommendations, fraud rings | Graph database |
Other kinds of NoSQL
| Kind | Examples | Stores data as |
|---|---|---|
| Document | MongoDB, Firestore, Couchbase | JSON-like documents |
| Key-value | Redis, Valkey, DynamoDB | A key and its value, like a giant Map |
| Wide-column | Cassandra, ScyllaDB, Bigtable | Rows with flexible column families, spread over many machines |
| Graph | Neo4j, Amazon Neptune | Nodes and the relationships between them |
Watch the lesson
NoSQL and MongoDB · 1/6
Not every database uses tables. Today we meet NoSQL, and its most famous member, MongoDB.
Prefer a video by a teacher? Find free videos on “mongodb crash course for beginners” on YouTube ↗
In real life: An order on a food delivery app
A food delivery backend can store each order as one document. The dishes, quantities and prices at the moment of ordering are embedded inside the order, because they are always shown together and must not change later. The customer and the restaurant are referenced by id, because one customer places hundreds of orders and their phone number may change. Showing "My orders" is then one fast read per order, with no joins.
{
"_id": "ord_9012",
"customerId": "cus_311",
"restaurantId": "res_77",
"status": "delivered",
"items": [
{ "name": "Veg biryani", "price": 220, "qty": 1 },
{ "name": "Gulab jamun", "price": 60, "qty": 2 }
]
}Practice (0/3 done)
Order items are embedded inside an order document. Write a function orderTotal(order) that returns the sum of price * qty for every item in order.items. An order with no items has total 0.
Build a tiny version of MongoDB find. Write find(docs, filter) that returns the documents matching every key in filter. A plain value means equality ({ category: "phone" }). An object with $gt means greater than ({ price: { $gt: 20000 } }). An empty filter {} returns all documents.
Design MongoDB documents for a college fest app with students, events and registrations. For each piece of data, decide: embed or reference? Write one sample document for an event.
Quick quiz
Read more (free)
Pass the quiz (60% or more) or mark this topic as done when you are ready.
Your progress is saved on this device only.