AlgoInsight

Q&A

What is data modeling in MongoDB?

By AlgoInsight Team2026-06-18data-structuresdatabasesmongodb

Overview

MongoDB stores data as BSON documents in collections. There's no fixed schema, and "foreign keys" are replaced by a deliberate design choice: embed related data directly in the parent document, or store it separately and reference it by ObjectId. Each choice has trade-offs. The fundamental question is: "How does the application access this data?"

graph TD
    A[MongoDB data modeling] --> B[Embedded documents]
    A --> C[Referenced documents]
    B --> B1["One document, one read<br/>Fast reads, atomic updates<br/>Data duplication if reused"]
    C --> C1["Separate docs, join in app / $lookup<br/>Normalized, single source of truth<br/>Multiple reads required"]
    style B fill:#1e1b4b,color:#fff

Embedding (Denormalized)

Store related data inside the parent document:

{
  "_id": "order_001",
  "customer": "Ada",
  "items": [
    { "product": "Widget A", "qty": 2, "price": 9.99 },
    { "product": "Widget B", "qty": 1, "price": 24.99 }
  ],
  "address": {
    "street": "1 Tech Lane",
    "city": "London"
  }
}

Benefits: One query fetches everything; writes that touch only this document are atomic; no join needed.

Choose embedding when:

Referencing (Normalized)

Store the related data in its own collection and link by _id:

// orders collection
{
  "_id": "order_001",
  "customer_id": ObjectId("64a1..."),   // reference
  "product_ids": [ObjectId("..."), ObjectId("...")]
}

// customers collection
{ "_id": ObjectId("64a1..."), "name": "Ada", "email": "ada@example.com" }

Benefits: Single source of truth; no data duplication; fields change in one place.

Choose referencing when:

One-to-N Relationship Patterns

Cardinality Strategy
One-to-few (1–dozens) Embed in array
One-to-many (hundreds+) Reference from the "many" side, or in an array if bounded
One-to-squillions (unbounded logs, events) Reference from the child; don't put an unbounded array in the parent

Schema Design Anti-Patterns to Avoid

  1. Unbounded arrays - embedding an ever-growing list (e.g. all log entries) in one document will hit the 16 MB limit and hurt performance.
  2. Massive number of collections - one collection per user/entity instead of a generic collection with a discriminator field.
  3. Over-normalizing - splitting data that is always accessed together into separate collections just out of habit from relational databases.
  4. Unnecessary $lookups - if every query joins two collections, consider embedding.

Practical Pattern: Bucket Pattern

For time-series or unbounded data, "bucket" related records:

// Instead of one document per sensor reading (millions):
{
  "sensor_id": "s1",
  "date": "2026-06-01",
  "readings": [23.1, 23.4, 22.9 ...]  // one doc per day, array of hourly readings
}

Why This Matters in Interviews

MongoDB system-design interviews always ask about data modeling. The key principles: model for query patterns (co-locate data that's read together); the embed vs reference trade-off (simplicity/speed vs normalization); specific cardinality rules (embed "few," reference large/unbounded arrays); and the most common anti-patterns (unbounded arrays, over-normalizing). Mentioning the 16 MB document limit and that $lookup is less efficient than embedding - but necessary for shared/large data - shows practical depth.

Common Pitfalls

References

More answers