Why Real-World Schemas Matter
Learning to model data for real applications — ecommerce stores and hospital management systems — teaches you how professional backend developers think about data relationships, scalability, and query patterns. These are two of the most common domain models asked about in Indian tech company interviews.
---
Ecommerce Data Model
An ecommerce backend needs to handle: user accounts, product listings, categories, shopping carts, orders, payments, and reviews. Here is how each entity maps to a Mongoose schema:
User Schema (Ecommerce)
name,email,password(hashed)role: 'customer' | 'admin' | 'seller'address: array of address objects (embedded — a user can have multiple saved addresses)wishlist: array of Product ObjectIds (referenced)resetPasswordToken,resetPasswordExpiryfor forgot-password flow
Product Schema
name,description,price,discountPercentagefinalPrice(virtual: price - discount)category: ObjectId ref to Categorybrand: Stringstock: Number (how many units available)images: array of{ url: String, public_id: String }(Cloudinary)ratings: Number (average, computed via aggregation)numOfReviews: Numberseller: ObjectId ref to User
Category Schema
name,description,imageparent: ObjectId ref to Category (self-reference for subcategories: Electronics > Mobile Phones > Smartphones)
Order Schema
user: ObjectId ref to UserorderItems: array of{ product: ObjectId, name, image, price, quantity }(embed snapshot — price at time of order)shippingAddress: embedded objectitemsPrice,taxPrice,shippingPrice,totalPricepaymentInfo:{ id: String, status: String }(Razorpay/Stripe payment ID)paidAt: DateorderStatus: 'Processing' | 'Shipped' | 'Delivered' | 'Cancelled'deliveredAt: Date
Order items embed a snapshot of the product name, image, and price at the time of purchase. This is intentional — if the product is later updated or deleted, the order history remains accurate.
Cart Schema
user: ObjectId ref to User (one cart per user)items: array of{ product: ObjectId ref Product, quantity: Number }totalPrice: virtual or computed field
Review Schema
user: ObjectId ref to Userproduct: ObjectId ref to Productrating: Number (1-5)comment: Stringtitle: String (review headline)- Compound unique index on
(user, product)— one review per product per user
---
Hospital Management Data Model
A hospital management system handles patients, doctors, appointments, medical records, and prescriptions. This domain is frequently asked about in college projects and government tech company interviews.
Patient Schema
firstName,lastName,email,phonedateOfBirth,genderbloodGroup: enum ['A+', 'A-', 'B+', 'B-', 'AB+', 'AB-', 'O+', 'O-']address: embedded objectemergencyContact: embedded{ name, phone, relation }medicalHistory: array of embedded{ condition, diagnosedDate, notes }allergies: array of strings
Doctor Schema
firstName,lastName,email,phonespecialization: String (Cardiologist, Orthopedist, General Physician, etc.)qualifications: array of strings (MBBS, MD, etc.)licenseNumber: String (unique)department: ObjectId ref to Departmentschedule: array of{ day: String, startTime: String, endTime: String, maxPatients: Number }consultationFee: Numberrating: Number (average from patient reviews)
Appointment Schema
patient: ObjectId ref to Patientdoctor: ObjectId ref to DoctorappointmentDate: DatetimeSlot: String ('09:00', '09:30', '10:00', ...)type: 'in-person' | 'online'status: 'scheduled' | 'confirmed' | 'in-progress' | 'completed' | 'cancelled' | 'no-show'symptoms: String (patient-reported symptoms)notes: String (doctor's internal notes)followUpDate: Date (optional)- Compound unique index on
(doctor, appointmentDate, timeSlot)— prevent double booking
Prescription Schema
appointment: ObjectId ref to Appointmentpatient: ObjectId ref to Patientdoctor: ObjectId ref to Doctordiagnosis: Stringmedicines: array of{ name, dosage, frequency, duration, instructions }tests: array of strings (blood test, X-ray, etc.)notes: String (diet, lifestyle recommendations)issuedAt: Date
---
Relationship Summary
| Relationship | Type | Implementation |
|---|---|---|
| User → Orders | One-to-many | Order has user: ObjectId |
| Product → Category | Many-to-one | Product has category: ObjectId |
| Order → Products | Many-to-many | Order.orderItems embeds product snapshot |
| Patient → Appointments | One-to-many | Appointment has patient: ObjectId |
| Doctor → Appointments | One-to-many | Appointment has doctor: ObjectId |
| Appointment → Prescription | One-to-one | Prescription has appointment: ObjectId |
---
Why These Designs Are Industry-Standard
- Separation of concerns: Each entity has its own schema/collection
- Snapshot pattern: Order items and prescriptions embed critical data at the time of creation to prevent data inconsistency when source records change
- Compound indexes: Prevent logical duplicates (one cart per user, one review per product per user, no double-booking)
- Flexible enums: Status fields use string enums for readability and easy extension
- Computed fields:
totalPricecalculated fromitemsPrice + taxPrice + shippingPriceavoids data drift