Facebook Pixel

DevTinder Database Design and Schema MongoDB Collections and Relationships

Learn the complete database design for DevTinder MongoDB collections, Mongoose schemas, relationships between users, connection requests, and messages, and indexing strategies.

DevTinder Database Design and Schema

The DevTinder database is built on MongoDB with Mongoose as the ODM. This guide covers all collections, their schemas, relationships, and indexing strategies.

Collections Overview

DevTinder has three main collections:

  1. users User profiles (name, email, password, photo, skills, about)
  2. connectionrequests Connection requests between users (from, to, status)
  3. messages Chat messages between connected users (sender, receiver, text)

User Schema

const userSchema = new mongoose.Schema({ firstName: { type: String, required: true, trim: true, minLength: 2, maxLength: 50 }, lastName: { type: String, trim: true, maxLength: 50 }, email: { type: String, required: true, unique: true, lowercase: true, trim: true, validate(value) { if (!validator.isEmail(value)) { throw new Error("Invalid email"); } } }, password: { type: String, required: true, minLength: 8, validate(value) { if (!validator.isStrongPassword(value)) { throw new Error("Password too weak"); } } }, photoUrl: { type: String, default: "https://default-avatar.png" }, age: { type: Number, min: 18 }, gender: { type: String, enum: ["male", "female", "other"] }, about: { type: String, maxLength: 500, default: "Tell us about yourself" }, skills: { type: [String], validate: { validator: function(skills) { return skills.length <= 10; }, message: "Cannot have more than 10 skills" } } }, { timestamps: true });

Key features:

  • Email validation with validator package
  • Strong password validation
  • Unique index on email (automatic via unique: true)
  • Timestamps for createdAt and updatedAt
  • Array field for skills with max length validation

ConnectionRequest Schema

const connectionRequestSchema = new mongoose.Schema({ fromUserId: { type: mongoose.Schema.Types.ObjectId, ref: "User", required: true }, toUserId: { type: mongoose.Schema.Types.ObjectId, ref: "User", required: true }, status: { type: String, required: true, enum: ["interested", "ignored", "accepted", "rejected"] } }, { timestamps: true }); // Compound unique index prevents duplicate requests connectionRequestSchema.index( { fromUserId: 1, toUserId: 1 }, { unique: true } );

Key features:

  • ObjectId references to User collection
  • Status enum with four possible values
  • Compound unique index prevents duplicate requests between the same pair
  • Timestamps for tracking when the request was sent and reviewed

Message Schema

const messageSchema = new mongoose.Schema({ senderId: { type: mongoose.Schema.Types.ObjectId, ref: "User", required: true }, receiverId: { type: mongoose.Schema.Types.ObjectId, ref: "User", required: true }, text: { type: String, required: true, maxLength: 1000 } }, { timestamps: true }); // Index for efficient message history queries messageSchema.index({ senderId: 1, receiverId: 1, createdAt: -1 });

Key features:

  • References to both sender and receiver
  • Text field with max length
  • Compound index on senderId, receiverId, and createdAt for efficient pagination of message history

Relationships

The relationships are:

  • User → ConnectionRequest One-to-many (a user can send/receive many requests)
  • User → Message One-to-many (a user can send/receive many messages)
  • ConnectionRequest → User Many-to-one (each request references two users)

These are implemented using ObjectId references and populate() to fetch related documents.

Indexing Strategy

Indexes are critical for performance as the user base grows:

CollectionIndexPurpose
usersemail (unique)Fast login lookups, prevent duplicates
connectionrequestsfromUserId + toUserId (unique)Prevent duplicate requests
connectionrequeststoUserId + statusFast query for pending requests
messagessenderId + receiverId + createdAtFast message history pagination

The Takeaway

The DevTinder database has three collections: users (profiles), connectionrequests (connections), and messages (chat). Each schema uses proper validation, references (ref) for relationships, and strategic indexes for performance. The compound unique index on connection requests prevents duplicates, and the message index enables efficient pagination of chat history.

Three collections: users (user profiles with name, email, password, photo, skills, about), connectionrequests (connection requests with from, to, status), and messages (chat messages with sender, receiver, text).

Using ObjectId references (ref) in Mongoose. ConnectionRequest references two users (fromUserId, toUserId). Message references sender and receiver. Use populate() to fetch the full user document when needed.

The compound unique index on fromUserId and toUserId prevents duplicate connection requests between the same pair of users at the database level, ensuring data integrity even if the application logic fails.

A compound index on senderId, receiverId, and createdAt (descending). This optimizes the most common query fetching message history between two users in reverse chronological order with pagination.

Email validation with the validator package (isEmail), strong password validation (isStrongPassword), minimum age of 18, max 10 skills, trimmed and length-limited name fields, and unique lowercase email.

Ready to master Node.js completely?

Want to upskill yourself, crack your next interview, and get your dream job? Join our comprehensive course to dive deeper with high-quality video tutorials, solve interview questions, and a premium community.

Please Login.
Please Login.
Please Login.
Please Login.