What is MongoDB? NoSQL vs Relational Databases

MongoDB is the “M” in MERN β€” the database that stores all of your application’s data. Unlike the relational databases you may have used before (MySQL, PostgreSQL, SQLite), MongoDB does not organise data into rigid tables with fixed columns and rows. Instead it stores data as flexible, JSON-like documents grouped into collections. This document model is a natural fit for JavaScript applications because the data format β€” essentially a JSON object β€” maps directly to the JavaScript objects you already work with in your code. In this lesson you will understand what MongoDB is, how it differs from relational databases, and why it is the standard database choice for the MERN stack.

Relational vs Document Databases

Concept Relational (MySQL / PostgreSQL) MongoDB
Basic unit of storage Row in a table Document in a collection
Schema Fixed β€” all rows must match the table schema Flexible β€” documents in the same collection can have different fields
Data format Typed columns (VARCHAR, INT, DATE…) JSON-like BSON objects with nested fields and arrays
Relationships Foreign keys and JOIN operations Embedded documents or ObjectId references
Query language SQL (Structured Query Language) MongoDB Query Language (MQL) β€” JSON-based operators
Scaling Primarily vertical (bigger server) Horizontal (sharding across many servers)
Transactions ACID transactions β€” strong by default ACID transactions supported (multi-document since v4.0)
Note: MongoDB is described as a NoSQL database β€” but this does not mean it has no structure at all. “NoSQL” simply means it does not use SQL as its query language and does not organise data in relational tables. MongoDB has its own rich query language, supports indexes, enforces data types through Mongoose schemas, and even supports ACID multi-document transactions since version 4.0.
Tip: The decision between MongoDB and a relational database is not about which one is better β€” it is about which one fits your data’s shape. MongoDB excels when your data is document-shaped (a blog post with an embedded author, tags array, and metadata), evolves quickly (you add fields without migrations), and needs to scale horizontally. Relational databases excel when your data is highly normalised, deeply relational (many-to-many joins), and requires strong ACID guarantees across many tables.
Warning: MongoDB’s schema flexibility is a feature, but it can become a liability without discipline. Without a Mongoose schema, two developers writing to the same collection can produce inconsistent documents with different field names, missing required data, or wrong types. Always define a Mongoose schema for every collection you use in your MERN application β€” it enforces structure at the application layer while keeping MongoDB’s underlying flexibility.

Why MongoDB Fits the MERN Stack

Reason Detail
Same data format MongoDB stores BSON (Binary JSON) β€” your Node.js code works with plain JavaScript objects with no conversion needed
Schema flexibility Early in development you can iterate on your data model without painful database migrations
JavaScript-friendly queries MQL queries are JavaScript objects β€” { published: true, tags: 'mern' } β€” not SQL strings to construct and sanitise
Mongoose ODM Mongoose bridges Node.js and MongoDB with schemas, validation, hooks, and a clean async API
Atlas free tier MongoDB Atlas provides a permanently free cloud cluster β€” no infrastructure to manage for learning and small projects
JSON throughout Data flows from MongoDB β†’ Express β†’ React as JSON with no transformation layer needed

The MongoDB Data Model β€” A Blog Post Example

// In a relational database, this blog post spans THREE tables:
// posts table:    post_id | title | body | author_id | created_at
// post_tags:      post_id | tag_id
// tags table:     tag_id  | name

// In MongoDB, it is ONE document:
{
  "_id":       "64a1f2b3c8e4d5f6a7b8c9d0",
  "title":     "Getting Started with MERN",
  "slug":      "getting-started-with-mern",
  "body":      "The MERN stack is a powerful combination...",
  "excerpt":   "A complete guide to building full-stack apps.",
  "author": {
    "_id":    "64a1f2b3c8e4d5f6a7b8c9d1",
    "name":   "Jane Smith",
    "avatar": "https://cdn.example.com/jane.jpg"
  },
  "tags":      ["mern", "javascript", "beginner"],
  "published": true,
  "featured":  false,
  "viewCount": 142,
  "createdAt": "2025-01-01T00:00:00.000Z",
  "updatedAt": "2025-01-15T10:30:00.000Z"
}
// The author is embedded β€” no JOIN needed to display a post with author info

MongoDB Architecture

MongoDB Server (mongod process β€” localhost:27017 or Atlas cluster)
β”‚
β”œβ”€β”€ Database: blogdb
β”‚   β”œβ”€β”€ Collection: posts        ← like a table, but schema-flexible
β”‚   β”‚   β”œβ”€β”€ Document: { _id, title, body, author, tags, ... }
β”‚   β”‚   β”œβ”€β”€ Document: { _id, title, body, author, tags, ... }
β”‚   β”‚   └── Document: { _id, title, body, ... }  ← can have extra fields
β”‚   β”‚
β”‚   β”œβ”€β”€ Collection: users
β”‚   β”‚   └── Document: { _id, name, email, password, role, ... }
β”‚   β”‚
β”‚   └── Collection: comments
β”‚       └── Document: { _id, postId, author, body, createdAt }
β”‚
└── Database: admin              ← MongoDB system database (do not modify)

MongoDB vs MySQL β€” Blog Post Query

── MySQL: Get a post with author and tags ────────────────────────────────────
SELECT p.*, u.name, u.avatar, GROUP_CONCAT(t.name) AS tags
FROM posts p
JOIN users u ON p.author_id = u.id
LEFT JOIN post_tags pt ON p.id = pt.post_id
LEFT JOIN tags t ON pt.tag_id = t.id
WHERE p.slug = 'getting-started-with-mern'
GROUP BY p.id;

── MongoDB (Mongoose): Get the same post ─────────────────────────────────────
await Post.findOne({ slug: 'getting-started-with-mern' })
  .populate('author', 'name avatar');
// Tags are already embedded in the document β€” no JOIN needed

Common Mistakes

Mistake 1 β€” Choosing MongoDB for every project regardless of data shape

❌ Wrong β€” using MongoDB for data that is fundamentally relational:

Accounting software with double-entry bookkeeping, complex multi-table constraints,
and strict ACID requirements across dozens of related records
β†’ A relational database (PostgreSQL) is a better fit here

βœ… Correct β€” evaluate the data shape first. MongoDB is ideal for documents (blog posts, products, user profiles, activity logs). Relational databases are ideal for deeply interconnected, highly normalised data with complex integrity constraints.

Mistake 2 β€” Ignoring Mongoose schemas because MongoDB is “schemaless”

❌ Wrong β€” writing directly to MongoDB without any schema enforcement:

// Without schema β€” anything goes
db.collection('posts').insertOne({ title: 123, random_field: true });
// Now your posts collection has inconsistent documents

βœ… Correct β€” always define a Mongoose schema. MongoDB’s flexibility is for the database layer β€” your application layer should always enforce structure.

Mistake 3 β€” Storing ObjectIds as strings in references

❌ Wrong β€” storing another document’s ID as a plain string:

{ author: "64a1f2b3c8e4d5f6a7b8c9d1" }  // plain string β€” populate() won't work

βœ… Correct β€” use the ObjectId type for references so Mongoose’s populate() can resolve them:

author: { type: mongoose.Schema.Types.ObjectId, ref: 'User' }  // βœ“

Quick Reference

Concept MongoDB Term SQL Equivalent
The server process mongod mysqld / postgres
A database Database Database / Schema
A group of similar data Collection Table
A single record Document Row
A field in a record Field Column
Unique record identifier _id (ObjectId) Primary Key (INT / UUID)
Related record reference ObjectId reference Foreign Key
Query language MQL (JSON-based) SQL

🧠 Test Yourself

A blog post in MongoDB has an embedded author object containing name and avatar. In MySQL the same data would require a JOIN between the posts and users tables. What is the main advantage of the MongoDB embedded approach for this use case?