Tech TutorBangla Web Documentation
Portfolio
HomeHTMLCSSTailwind CSSJavaScriptTypeScriptReactNext.jsNode.jsExpressSocket.IOExpoWordPressPostgreSQLPrismaPostgresNestJSMongoDBDockerTanStackTanStack TableRTK QueryGitGitHub
  • MongoDB Documentation21টি অধ্যায়
প্রযুক্তি নির্বাচন
HomeHTMLCSSTailwind CSSJavaScriptTypeScriptReactNext.jsNode.jsExpressSocket.IOExpoWordPressPostgreSQLPrismaPostgresNestJSMongoDBDockerTanStackTanStack TableRTK QueryGitGitHub
  • Introduction
  • কেন Mongoose?
  • Installation
  • Connection
  • Schema
  • Model
  • Document
  • CRUD
  • Querying
  • Validation
  • Middleware
  • Population
  • Aggregation
  • Virtuals
  • Indexes
  • Error Handling
  • Update Operators
  • Transactions
  • Express Integration
  • Blog Project
  • Best Practices
  1. Docs
  2. MongoDB
  3. Real Project: Blog
MongoDBAdvanced

Real Project: Blog

User, Post, Comment — তিনটি collection-এর সাথে populate, aggregation ও subdocument দিয়ে পূর্ণাঙ্গ ব্লগ — বাংলায়।

9টি অংশবাংলা ভাষায়

Schema ডিজাইন

models/Post.jsjs
js
import mongoose from "mongoose";

const commentSchema = new mongoose.Schema(
  {
    author: { type: mongoose.Schema.Types.ObjectId, ref: "User", required: true },
    body: { type: String, required: true, minlength: 1 },
    likes: [{ type: mongoose.Schema.Types.ObjectId, ref: "User" }],
  },
  { timestamps: true }
);

const postSchema = new mongoose.Schema(
  {
    title: { type: String, required: true, maxlength: 120 },
    slug: { type: String, unique: true, index: true },
    body: { type: String, required: true },
    author: { type: mongoose.Schema.Types.ObjectId, ref: "User", required: true },
    tags: [String],
    views: { type: Number, default: 0 },
    comments: [commentSchema],
  },
  { timestamps: true }
);

// slug স্বয়ংক্রিয় তৈরি
postSchema.pre("save", function (next) {
  if (!this.slug) {
    this.slug =
      this.title.toLowerCase().replace(/[^a-z0-9]+/g, "-") +
      "-" +
      Math.random().toString(36).slice(2, 7);
  }
  next();
});

export default mongoose.model("Post", postSchema);

Post + author populate

post controllerjs
js
// home: latest posts + author
router.get("/", async (req, res, next) => {
  try {
    const posts = await Post.find()
      .populate("author", "name email")
      .sort({ createdAt: -1 })
      .limit(20)
      .lean();

    res.json(posts);
  } catch (err) {
    next(err);
  }
});

// single post — views বাড়িয়ে fields
router.get("/:slug", async (req, res, next) => {
  try {
    const post = await Post.findOneAndUpdate(
      { slug: req.params.slug },
      { $inc: { views: 1 } },
      { new: true }
    )
      .populate({
        path: "author",
        select: "name",
      })
      .populate({
        path: "comments.author",
        select: "name",
      });

    if (!post) return res.status(404).json({ message: "Post নেই" });
    res.json(post);
  } catch (err) {
    next(err);
  }
});

Comment যোগ (subdocument)

comment routejs
js
router.post("/:slug/comments", async (req, res, next) => {
  try {
    const post = await Post.findOne({ slug: req.params.slug });
    if (!post) return res.status(404).json({ message: "Post নেই" });

    post.comments.push({
      author: req.body.author, // logged-in user ID
      body: req.body.body,
    });

    await post.save(); // subdocument validation-ও হবে
    res.status(201).json(post.comments);
  } catch (err) {
    next(err);
  }
});

Aggregation — top post

Stats pipelinejs
js
// সবচেয়ে বেশি comment-এর পোস্ট ৫টি
const topCommented = await Post.aggregate([
  { $project: { title: 1, commentCount: { $size: "$comments" }, views: 1 } },
  { $sort: { commentCount: -1, views: -1 } },
  { $limit: 5 },
]);

// tag ধরে গড় views
const tagStats = await Post.aggregate([
  { $unwind: "$tags" },
  {
    $group: {
      _id: "$tags",
      avgViews: { $avg: "$views" },
      total: { $sum: 1 },
    },
  },
  { $sort: { total: -1 } },
]);
Subdocument vs separate collection

Comment-গুলো post-এর subdocument রাখলে পড়া দ্রুত এবং populate লাগে। তবে comment অনেক এনে ব্লগে (লাখো+) আলাদা collection + $lookup বা separate ref ভালো — পরিস্থিতি অনুযায়ী ডিজাইন বেছে নিন।

শেষ প্যারায় নিজে practice করুন — কোড কপি করে নিজের এডিটরে চালিয়ে দেখুন।
আগেরExpress + Mongoose REST APIপরেরMongoose Best Practices
এই পেজে
Tech Tutor

বাংলায় ওয়েব ডেভেলপমেন্ট ডকুমেন্টেশন শিখুন — ধাপে ধাপে।

Homeসব ডকুমেন্টেশনQuick Startআমার নোটস

© 2026 Tech Tutor. বাংলায় শিখুন, বাংলায় গড়ুন।

mdanamolhasan1998@gmail.com