Back-EndSchemas
Social Media Schema
Complete MongoDB schemas for a social media app — Post, Like, Comment, Follow, and Notification.
Social Media Schema
Schemas for a social platform — posts with embedded likes for fast access, a separate Follow model for the social graph, and notifications.
Post Schema
// src/models/post.model.js
import mongoose from "mongoose";
const postSchema = new mongoose.Schema(
{
author: {
type: mongoose.Schema.Types.ObjectId,
ref: "User",
required: true,
},
content: {
type: String,
maxlength: 500,
},
images: [{ type: String }],
// likes stored as an array of user ids — fast for small-medium scale
likes: [{ type: mongoose.Schema.Types.ObjectId, ref: "User" }],
commentsCount: {
type: Number,
default: 0,
},
sharesCount: {
type: Number,
default: 0,
},
},
{ timestamps: true }
);
const Post = mongoose.model("Post", postSchema);
export default Post;Comment Schema
// src/models/comment.model.js
import mongoose from "mongoose";
const commentSchema = new mongoose.Schema(
{
post: {
type: mongoose.Schema.Types.ObjectId,
ref: "Post",
required: true,
},
author: {
type: mongoose.Schema.Types.ObjectId,
ref: "User",
required: true,
},
content: {
type: String,
required: true,
maxlength: 300,
},
likes: [{ type: mongoose.Schema.Types.ObjectId, ref: "User" }],
},
{ timestamps: true }
);
const Comment = mongoose.model("Comment", commentSchema);
export default Comment;Follow Schema
// src/models/follow.model.js
import mongoose from "mongoose";
const followSchema = new mongoose.Schema(
{
follower: {
type: mongoose.Schema.Types.ObjectId,
ref: "User",
required: true,
},
following: {
type: mongoose.Schema.Types.ObjectId,
ref: "User",
required: true,
},
},
{ timestamps: true }
);
// prevent following the same person twice
followSchema.index({ follower: 1, following: 1 }, { unique: true });
const Follow = mongoose.model("Follow", followSchema);
export default Follow;Notification Schema
// src/models/notification.model.js
import mongoose from "mongoose";
const notificationSchema = new mongoose.Schema(
{
recipient: {
type: mongoose.Schema.Types.ObjectId,
ref: "User",
required: true,
},
sender: {
type: mongoose.Schema.Types.ObjectId,
ref: "User",
required: true,
},
type: {
type: String,
enum: ["like", "comment", "follow", "mention"],
required: true,
},
post: {
type: mongoose.Schema.Types.ObjectId,
ref: "Post",
},
isRead: {
type: Boolean,
default: false,
},
},
{ timestamps: true }
);
const Notification = mongoose.model("Notification", notificationSchema);
export default Notification;Common Usage Patterns
// toggle a like on a post
const post = await Post.findById(postId);
const alreadyLiked = post.likes.includes(userId);
if (alreadyLiked) {
post.likes.pull(userId);
} else {
post.likes.push(userId);
// create a notification for the post author
await Notification.create({
recipient: post.author,
sender: userId,
type: "like",
post: post._id,
});
}
await post.save();// follow a user
await Follow.create({ follower: currentUserId, following: targetUserId });
await Notification.create({
recipient: targetUserId,
sender: currentUserId,
type: "follow",
});// get a user's follower count and following count
const followerCount = await Follow.countDocuments({ following: userId });
const followingCount = await Follow.countDocuments({ follower: userId });Storing likes as an embedded array on Post works well at small to medium scale. For apps with millions of likes per post, switch to a separate Like collection with post and user fields, similar to the Follow model — embedded arrays become slow to update at very large sizes.
Summary
Post.likesis an embedded array of user ids — simple and fast for typical app sizesFollowis a separate collection with a compound unique index onfollower + following— this is the standard pattern for social graphs, not an embedded array onUserNotificationtrackstypewith an enum so the frontend can render different notification messages and icons- Use
.pull()and.push()on Mongoose arrays to toggle likes without re-fetching the whole array manually - At very large scale, move
likesfrom an embedded array to its own collection likeFollow