Skip to content

Intermediate · NoSQL, ORMs and data features · topic 27 of 54 · 30 min

NoSQL and MongoDB

Explanation

NoSQL databases do not keep data in tables of rows and columns. MongoDB, the most popular one, stores JSON-like documents inside collections. It is handy when each record has a different shape, but for money, stock and data with many links, a SQL database is usually the safer choice.

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.

Think of it like this: A SQL table is like a ruled attendance register: every row has exactly the same columns. A MongoDB collection is like a file of filled-in forms: most forms look alike, but one form can have an extra page stapled to it and nobody complains.
json
{
  "_id": "66f1c0a2e4b0a1b2c3d4e5f6",
  "name": "Redmi 13",
  "brand": "Redmi",
  "category": "phone",
  "price": 11999,
  "specs": { "ram": "6 GB", "storage": "128 GB" },
  "colours": ["black", "blue"]
}
One MongoDB document: nested objects and lists live inside the record. _id is added automatically.

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.

javascript
// 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 } });
find, $gt, $in, insertOne and updateOne with $set. Shown as an example.
SQL wordMongoDB word
TableCollection
RowDocument
ColumnField
SELECT ... WHEREfind(filter)
INSERTinsertOne / insertMany
UPDATE ... SETupdateOne(filter, { $set: ... })
JOINEmbedding, 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

SituationUsually better
Money, bookings, stock counts (need strict transactions and constraints)SQL (PostgreSQL, MySQL)
Data with many links between tables, lots of reportsSQL
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, countersKey-value (Redis)
Friends-of-friends, recommendations, fraud ringsGraph database

Other kinds of NoSQL

KindExamplesStores data as
DocumentMongoDB, Firestore, CouchbaseJSON-like documents
Key-valueRedis, Valkey, DynamoDBA key and its value, like a giant Map
Wide-columnCassandra, ScyllaDB, BigtableRows with flexible column families, spread over many machines
GraphNeo4j, Amazon NeptuneNodes and the relationships between them
Tip: For a new app, PostgreSQL is a safe default. It also has a JSONB column type, so you can keep flexible document-style data next to normal tables. Pick MongoDB when your data really is document-shaped.
Careful: "Schema-less" does not mean "no rules". Validate every document in your code (or with MongoDB schema validation). Never pass req.body straight into a filter: a value like { "$ne": null } can match every user. This is called NoSQL injection.

Watch the lesson

NoSQL and MongoDB · 1/6

NoSQL and MongoDB

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.

json
{
  "_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 }
  ]
}
Items embedded; customer and restaurant referenced by id.

Practice (0/3 done)

Task 1 · Code · Javascript

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.

Task 2 · Code · Javascript

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.

Task 3 · Practice

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

Question 1

1.In MongoDB, what is a collection?

Question 2

2.Which filter finds products that cost more than 500?

Question 3

3.A post can get millions of comments. How should comments be stored?

Question 4

4.Which database type is Redis?

Question 5

5.What does updateOne({ name: "Pen" }, { $set: { price: 25 } }) do?

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.

← Previous: Normalisation and table design