MongoDB and Building Real APIs
Weeks 16 and 17 covered MongoDB operations and the development of a complete API from scratch.
MongoDB CRUD Operations
Creating Documents
insertOne creates a single document. insertMany creates multiple at once. MongoDB generates a unique _id for each document automatically.
Documents are flexible. They can have different fields even in the same collection. No fixed schema unless you enforce one with Mongoose.
Reading Documents
find returns all matching documents. findOne returns the first match. Query operators filter results.
Comparison operators: $gt for greater than, $lt for less than, $gte and $lte for greater-than-or-equal-to and less-than-or-equal-to ranges. $in for matching any value in an array. $ne for not equal.
Logical operators: $and and $or combine conditions. Pattern matching with regular expressions.
Projection selects which fields to return. Limit and skip enable pagination. Sort the results.
Updating Documents
updateOne modifies the first matching document. updateMany modifies all matches.
$set replaces field values. $inc increments numbers. $push adds to arrays. $pull removes from arrays.
Upsert creates a document if it doesn't exist, updates it if it does. One operation instead of checking, then creating or updating.
Deleting Documents
deleteOne removes the first match. deleteMany removes all matches. Drop removes the entire collection.
Advanced Queries
**Embedded Documents
**MongoDB stores related data inside documents instead of separate tables.
Querying embedded fields uses dot notation. Finding posts by author name: { "author.name": "John" }.
Arrays of embedded documents work similarly. Finding posts with specific comments: { "comments.user": "Alice" }.
Aggregation Pipeline
Aggregation transforms data through stages. Each stage processes documents and passes results to the next.
$match filters documents like find. $group aggregates data like SQL GROUP BY.
Grouping posts by author and counting: group by author name, sum 1 for each document, and sum the likes field.
Tech Opportunity Tracker API
Built a complete API for tracking tech opportunities.
The Data Model
Opportunities have a title, type, deadline, status, and notes. Type is an enum: hackathon, internship, fellowship, or job. Status is an enum: interested, applied, rejected, or accepted.
Users have a name, email, and stack. Email is unique and validated. Stack is an array of technologies.
Opportunities reference users. One user can have many opportunities.
Mongoose Schemas
Defined schemas with validation. Email validation, required fields, and enum restrictions.
The User schema enforces unique emails. The Opportunity schema uses enum to restrict type and status to specific values. References connect opportunities to users.
Building the API
Started with the MongoDB Atlas connection. Confirmed the connection works before adding models.
Created schemas and models. User model first, then Opportunity model with user reference.
Wrote a standalone script to test everything. Create a user, create opportunities for that user, fetch all opportunities, and populate user details. Confirmed it works before adding Express.
Built Express routes and controllers. Create user, get all opportunities, get one opportunity, create opportunity, update status, delete opportunity.
Error Handling
Handled duplicate email errors from MongoDB. Handled validation errors from Mongoose. Handled not-found cases when querying by ID.
Each error returns appropriate status codes and messages. 400 for validation, 404 for not found, 409 for duplicates, 500 for server errors.
Query Filtering
Added query parameters for filtering. GET /api/opportunities?status=applied returns only applied opportunities. GET /api/opportunities?type=hackathon returns only hackathons.
Both filters work together. GET /api/opportunities?status=applied&type=internship returns applied internships.
Dynamic query building. Start with an empty query object, add filters if query parameters exist, and pass to find.
Key Lessons
MongoDB documents are flexible. No fixed schema unless enforced.
Embedded documents avoid joins. Related data lives together.
Mongoose provides structure. Schemas, validation, and references work on top of MongoDB's flexibility.
Schema design matters. Deciding what to embed versus reference affects queries and performance.
Enum validation prevents invalid data. Status can only be one of the four defined values.
Error handling covers all cases. Validation, duplicates, not found, server errors. Each gets a proper response.
Moving Forward
Continuing with backend development. More advanced patterns and concepts.
Question: How do you decide when to embed documents versus reference them in MongoDB?
Top comments (0)