Practical Lab: Build Your First Learning Database
This lab combines the concepts from the chapter into a small learning-platform dataset. Run the commands in mongosh against a development database.
Step 1: Select the practice database
use mongodb_course_lab
Step 2: Insert sample courses
db.courses.insertMany([
{
slug: "mongodb-basics",
title: "MongoDB Basics",
category: "database",
level: "beginner",
durationMinutes: 120,
published: true,
tags: ["mongodb", "nosql", "backend"],
instructor: {
name: "Kavitha",
country: "India"
},
createdAt: ISODate("2026-10-01T09:00:00Z")
},
{
slug: "mongodb-querying",
title: "MongoDB Querying in Depth",
category: "database",
level: "intermediate",
durationMinutes: 240,
published: true,
tags: ["mongodb", "queries", "backend"],
instructor: {
name: "Arun",
country: "India"
},
createdAt: ISODate("2026-10-05T09:00:00Z")
},
{
slug: "react-foundations",
title: "React Foundations",
category: "frontend",
level: "beginner",
durationMinutes: 180,
published: false,
tags: ["react", "javascript", "frontend"],
instructor: {
name: "Meera",
country: "India"
},
createdAt: ISODate("2026-10-08T09:00:00Z")
},
{
slug: "mongodb-data-modeling",
title: "MongoDB Data Modeling",
category: "database",
level: "advanced",
durationMinutes: 360,
published: true,
tags: ["mongodb", "schema-design", "architecture"],
instructor: {
name: "Kavitha",
country: "India"
},
createdAt: ISODate("2026-10-12T09:00:00Z")
}
]);
Step 3: Inspect the inserted records
db.courses.find();
Observe the _id values generated by MongoDB. Inspect the arrays, nested instructor documents, dates, and scalar fields.
Step 4: Filter by category
db.courses.find({ category: "database" });
This query returns the database courses. It does not require every document in the collection to belong to that category.
Step 5: Query a nested field
db.courses.find({ "instructor.name": "Kavitha" });
The query uses dot notation to select courses taught by Kavitha.
Step 6: Filter by multiple conditions
db.courses.find({
category: "database",
published: true
});
Multiple fields in a standard query filter are combined using logical AND. A document must satisfy both conditions to match.
Step 7: Return selected fields
db.courses.find(
{ published: true },
{ _id: 0, title: 1, level: 1, durationMinutes: 1 }
);
The first argument specifies which documents to match. The second argument specifies which fields to return. This projection excludes _id and includes the three requested fields.
Step 8: Count published courses
db.courses.countDocuments({ published: true });
With the supplied data, this should return 3.
Step 9: Inspect a date range
db.courses.find({
createdAt: {
$gte: ISODate("2026-10-05T00:00:00Z"),
$lt: ISODate("2026-10-13T00:00:00Z")
}
});
This query uses an inclusive lower bound and an exclusive upper bound. It returns documents created on or after October 5 and before October 13, 2026, according to the stored UTC dates.
Step 10: Clean up when finished
If this is a disposable practice database and you want to remove the lab collection, run:
db.courses.drop();
This deletes the collection and its documents. Do not run destructive commands against a production collection.
Lab challenges
- Find every course whose level is
beginner. - Find published courses taught by Arun.
- Return only
slugandtitlefor frontend courses. - Count all courses in the
databasecategory. - Find courses whose tags contain
backend. - Find courses created after October 5, 2026.
- Explain why
instructor.nameis a nested field path rather than a separate top-level field. - Describe one reason you might keep enrollments in a separate collection rather than embedding an unbounded enrollment history inside each course.
// 1. Beginner courses
db.courses.find({ level: "beginner" });
// 2. Published courses taught by Arun
db.courses.find({
published: true,
"instructor.name": "Arun"
});
// 3. Slug and title for frontend courses
db.courses.find(
{ category: "frontend" },
{ _id: 0, slug: 1, title: 1 }
);
// 4. Count database courses
db.courses.countDocuments({ category: "database" });
// 5. Courses whose tags contain backend
db.courses.find({ tags: "backend" });
// 6. Courses created after October 5, 2026
db.courses.find({
createdAt: { $gt: ISODate("2026-10-05T00:00:00Z") }
});{ tags: "backend" } matches documents whose tags array contains that value. The date example uses a BSON Date boundary rather than comparing strings.- A single collection can contain documents with nested fields and arrays.
- Multiple ordinary filter fields are combined using AND.
- Projection controls which fields are returned.
- Array fields can be queried by matching an element.
- BSON Date values support chronological range filtering.
- Destructive collection operations should be restricted to appropriate development environments.
Given the lab dataset, how many courses match `{ category: "database", published: true }`?