Project: Blog With Comments
Introduction
This project builds a blog with posts, tags, and comments using MongoDB modeling choices from earlier chapters. You implement embedded comments and referenced comments side by side, add indexes for list queries, and expose read APIs with PyMongo or FastAPI.
Prerequisites
- Embedded vs Referenced Modeling
- Common Modeling Patterns
- Indexes and Explain
- PyMongo Basics or PyMongo With FastAPI
Project Goals
| Feature | Notes |
|---|---|
| Post CRUD | title, slug, body, tags, published |
| Comments | embedded array or separate collection |
| List by date | sort createdAt, pagination |
| Lookup by slug | unique index on slug |
Data Models
Approach A: Embedded Comments (One-to-Few)
Add comment with $push:
db.posts.updateOne(
{ slug: "mongodb-blog-project" },
{
$push: {
comments: {
author: "Bob",
body: "Thanks!",
createdAt: new Date()
}
}
}
)Approach B: Referenced Comments (Scale)
posts:
db.posts.insertOne({
title: "Referenced Comments Post",
slug: "ref-comments-post",
body: "...",
tags: ["scale"],
published: true,
createdAt: new Date()
})comments:
db.comments.insertOne({
postId: ObjectId("..."),
author: "Carol",
body: "Referenced comment.",
createdAt: new Date()
})Query comments for a post:
db.comments.find({ postId: post._id }).sort({ createdAt: 1 })Indexes
db.posts.createIndex({ slug: 1 }, { unique: true })
db.posts.createIndex({ published: 1, createdAt: -1 })
db.comments.createIndex({ postId: 1, createdAt: 1 })Explain list query:
db.posts.find({ published: true }).sort({ createdAt: -1 }).limit(10).explain("executionStats")Expect IXSCAN, not COLLSCAN — Indexes chapter.
PyMongo: List and Add Comment (Referenced)
FastAPI Endpoints Sketch
Extend chapter 20 posts router:
Subset Pattern (Optional)
Homepage shows latest 3 comments embedded; full thread in comments collection — Common Modeling Patterns.
Post-Project Checklist
-
slugunique index enforced - Chose embedded vs referenced with written rationale
- List query uses compound index on
published + createdAt -
explainshows index use
FAQ
Which comment model should I ship?
Embedded for < ~100 comments per post and single-document reads. Referenced when comments grow large or need independent moderation.
Soft-delete posts?
Add deletedAt and filter deletedAt: { $exists: false } — Delete and TTL.
Full-text search on posts?
Text index on title and body — Indexes.
Auth for posting?
Add JWT on write routes — FastAPI JWT.
Next project?
Product catalog uses dynamic attributes.