From a8ba3112e6c08fc128cf7b353848285dfa7acb94 Mon Sep 17 00:00:00 2001 From: Diego Freniche Date: Wed, 10 Sep 2025 18:07:11 +0200 Subject: [PATCH] Added JavaScript and mongosh tabs to challenge solutions --- docs/40-CRUD/1-WHERE.mdx | 79 ++++++++++++--- docs/40-CRUD/2-SELECT.mdx | 54 +++++++++-- docs/40-CRUD/3-ORDER-LIMIT.mdx | 28 +++++- docs/40-CRUD/4-INSERT-DELETE.mdx | 122 +++++++++++++++++------- docs/40-CRUD/5-UPDATE.mdx | 33 +++++-- docs/50-aggregation/2-match-project.mdx | 60 +++++++++--- docs/50-aggregation/3-sort-limit.mdx | 8 +- docs/50-aggregation/4-group.mdx | 12 +-- docs/50-aggregation/5-lookup.mdx | 51 +++++++--- docs/50-aggregation/7-merge.mdx | 9 +- 10 files changed, 343 insertions(+), 113 deletions(-) diff --git a/docs/40-CRUD/1-WHERE.mdx b/docs/40-CRUD/1-WHERE.mdx index 1aebfd1..135f926 100644 --- a/docs/40-CRUD/1-WHERE.mdx +++ b/docs/40-CRUD/1-WHERE.mdx @@ -1,3 +1,6 @@ +import Tabs from "@theme/Tabs"; +import TabItem from "@theme/TabItem"; + # πŸ‘ WHERE β†’ .find() Similar to SQL's `WHERE` clause, the `.find()` method in MongoDB retrieves documents from a collection that matches a specified query. @@ -91,31 +94,77 @@ Now, translate the following into a MongoDB query.
Answer -
- ```js - db.books.find({ totalInventory: 5 }); - ``` -
+ + +
+ ```js + const cursor = await books.find({ totalInventory: 5 }); + + await cursor.forEach((b) => { + console.log(b); + }); + ``` +
+
+ +
+ ```js + db.books.find({ totalInventory: 5 }); + ``` +
+
+
+
#### 2. Find all books with more than 300 pages.
Answer -
- ```js - db.books.find({ pages: {$gt: 300} }); - ``` -
+ + +
+ ```js + const cursor = await books.find({ pages: {$gt: 300} }); + + await cursor.forEach((b) => { + console.log(b); + }); + ``` +
+
+ +
+ ```js + db.books.find({ pages: {$gt: 300} }); + ``` +
+
+
#### 3. Find books in the `Science` genre that are more than 300 pages long.
Answer -
- ```js - db.books.find({ "genre.name": "Science", pages: {$gt: 300} }); - ``` -
+ + +
+ ```js + const cursor = await books.find( { "genre.name": "Science", pages: {$gt: 300} } ); + + await cursor.forEach((b) => { + console.log(b); + }); + ``` +
+
+ +
+ ```js + db.books.find({ "genre.name": "Science", pages: {$gt: 300} }); + ``` +
+
+
diff --git a/docs/40-CRUD/2-SELECT.mdx b/docs/40-CRUD/2-SELECT.mdx index 5f7d24c..349e549 100644 --- a/docs/40-CRUD/2-SELECT.mdx +++ b/docs/40-CRUD/2-SELECT.mdx @@ -1,3 +1,6 @@ +import Tabs from "@theme/Tabs"; +import TabItem from "@theme/TabItem"; + # πŸ‘ SELECT β†’ projection In SQL, the `SELECT` statement allows us to specify which columns to retrieve from a table. Similarly, in MongoDB, we use **projection** in the `.find()` method to control which fields to include (or exclude) in query results. @@ -77,20 +80,51 @@ Here:
Answer -
- ```js - db.books.find({}, {title: 1, _id: 0}); - ``` -
+ + +
+ ```js + const cursor = await books.find({}).project( {title: 1, _id: 0} ).limit(10); + + await cursor.forEach((b) => { + console.log(b); + }); + ``` +
+ +
+ +
+ ```js + db.books.find({}, {title: 1, _id: 0}); + ``` +
+
+
### πŸ‘ 2. Retrieve all fields except `_id` and `authors` for books in the "History" genre.
Answer -
- ```js - db.books.find({ "genre.name": "History" }, { _id: 0, authors: 0 }); - ``` -
+ + +
+ ```js + const cursor = await books.find({ "genre.name": "History" }).project( { _id: 0, authors: 0 } ).limit(10); + + await cursor.forEach((b) => { + console.log(b); + }); + ``` +
+
+ +
+ ```js + db.books.find({ "genre.name": "History" }, { _id: 0, authors: 0 }); + ``` +
+
+
diff --git a/docs/40-CRUD/3-ORDER-LIMIT.mdx b/docs/40-CRUD/3-ORDER-LIMIT.mdx index 06b7a56..f41011a 100644 --- a/docs/40-CRUD/3-ORDER-LIMIT.mdx +++ b/docs/40-CRUD/3-ORDER-LIMIT.mdx @@ -1,3 +1,6 @@ +import Tabs from "@theme/Tabs"; +import TabItem from "@theme/TabItem"; + # πŸ‘ ORDER BY β†’ .sort() & LIMIT β†’ .limit() In SQL, we use `ORDER BY` to sort query results and `LIMIT` to restrict the number of returned rows. MongoDB provides the `.sort()` and `.limit()` methods to achieve the same. @@ -64,9 +67,24 @@ This returns the **top 10 available books** in the "Science Fiction" genre.
Answer -
- ```js - db.books.find({}).sort({title: 1}).limit(10) - ``` -
+ + +
+ ```js + const cursor = await books.find({}).sort({title: 1}).limit(10); + + await cursor.forEach((b) => { + console.log(b); + }); + ``` +
+
+ +
+ ```js + db.books.find({}).sort({title: 1}).limit(10) + ``` +
+
+
diff --git a/docs/40-CRUD/4-INSERT-DELETE.mdx b/docs/40-CRUD/4-INSERT-DELETE.mdx index dd2fa28..55bccb5 100644 --- a/docs/40-CRUD/4-INSERT-DELETE.mdx +++ b/docs/40-CRUD/4-INSERT-DELETE.mdx @@ -1,3 +1,6 @@ +import Tabs from "@theme/Tabs"; +import TabItem from "@theme/TabItem"; + # πŸ‘ INSERT β†’ insertOne() & DELETE β†’ deleteOne() MongoDB provides two methods for inserting documents into a collection: @@ -67,45 +70,94 @@ DELETE FROM reviews WHERE bookId = '0786222727';
Answer -
- ```js - db.reviews.insertMany([ - { - text: "Thrilling end.", - rating: 4, - name: "Mark", - bookId: "0786222727", - }, - { - text: "Must read!", - rating: 5, - name: "Raj", - bookId: "0786222727", - }, - { - text: "Very expensive", - rating: 3, - name: "Yun", - bookId: "0786222727", - }, - { - text: "Extremely satisfied with the storyline!", - rating: 5, - name: "Lisa", - bookId: "0786222727", - } - ]); - ``` -
+ + +
+ ```js + const reviews = db.collection("reviews"); + await reviews.insertMany([ + { + text: "Thrilling end.", + rating: 4, + name: "Mark", + bookId: "0786222727", + }, + { + text: "Must read!", + rating: 5, + name: "Raj", + bookId: "0786222727", + }, + { + text: "Very expensive", + rating: 3, + name: "Yun", + bookId: "0786222727", + }, + { + text: "Extremely satisfied with the storyline!", + rating: 5, + name: "Lisa", + bookId: "0786222727", + } + ]); + ``` +
+
+ +
+ ```js + db.reviews.insertMany([ + { + text: "Thrilling end.", + rating: 4, + name: "Mark", + bookId: "0786222727", + }, + { + text: "Must read!", + rating: 5, + name: "Raj", + bookId: "0786222727", + }, + { + text: "Very expensive", + rating: 3, + name: "Yun", + bookId: "0786222727", + }, + { + text: "Extremely satisfied with the storyline!", + rating: 5, + name: "Lisa", + bookId: "0786222727", + } + ]); + ``` +
+
+
### πŸ‘ 2. Delete all the reviews for `bookId` "0786222727" through a single command.
Answer -
- ```js - db.reviews.deleteMany({"bookId": "0786222727"}) - ``` -
+ + +
+ ```js + const reviews = db.collection("reviews"); + await reviews.deleteMany({"bookId": "0786222727"}) + ``` +
+
+ +
+ ```js + db.reviews.deleteMany({"bookId": "0786222727"}) + ``` +
+
+
diff --git a/docs/40-CRUD/5-UPDATE.mdx b/docs/40-CRUD/5-UPDATE.mdx index 190a26b..bf570f5 100644 --- a/docs/40-CRUD/5-UPDATE.mdx +++ b/docs/40-CRUD/5-UPDATE.mdx @@ -1,3 +1,6 @@ +import Tabs from "@theme/Tabs"; +import TabItem from "@theme/TabItem"; + # πŸ‘ UPDATE β†’ updateOne(), updateMany() To modify existing documents, MongoDB provides: @@ -82,12 +85,26 @@ Executing the above command will insert a fresh new document in the collection,
Answer -
- ```js - db.books.updateOne( - {"title": "Treasure of the Sun"}, - {$set: {pages: 449}} - ); - ``` -
+ + +
+ ```js + await books.updateOne( + {"title": "Treasure of the Sun"}, + {$set: {pages: 449}} + ); + ``` +
+
+ +
+ ```js + db.books.updateOne( + {"title": "Treasure of the Sun"}, + {$set: {pages: 449}} + ); + ``` +
+
+
diff --git a/docs/50-aggregation/2-match-project.mdx b/docs/50-aggregation/2-match-project.mdx index a5568c8..42cd40d 100644 --- a/docs/50-aggregation/2-match-project.mdx +++ b/docs/50-aggregation/2-match-project.mdx @@ -1,3 +1,6 @@ +import Tabs from "@theme/Tabs"; +import TabItem from "@theme/TabItem"; + # πŸ‘ $match and $project MongoDB’s **Aggregation Framework** allows for powerful data transformations and analysis. The **$match**, **$project**, and **$sort** stages are fundamental building blocks of an aggregation pipeline. @@ -96,25 +99,52 @@ db.books.aggregate([
Answer -
- ```js - db.books.aggregate([ - { $match: {available: {$gt: 2}}} - ]); - ``` -
+ + +
+ ```js + await books.aggregate([ + { $match: {available: {$gt: 2}}} + ]).toArray(); + ``` +
+
+ +
+ ```js + db.books.aggregate([ + { $match: {available: {$gt: 2}}} + ]); + ``` +
+
+
### πŸ‘ 2. Find books with more than 2 available copies. Return only book titles and publication year.
Answer -
- ```js - db.books.aggregate([ - { $match: {available: {$gt: 2}}}, - { $project: {title: 1, year: 1, _id: 0}} - ]); - ``` -
+ + +
+ ```js + await books.aggregate([ + { $match: {available: {$gt: 2}}}, + { $project: {title: 1, year: 1, _id: 0}} + ]).toArray(); + ``` +
+
+ +
+ ```js + db.books.aggregate([ + { $match: {available: {$gt: 2}}}, + { $project: {title: 1, year: 1, _id: 0}} + ]); + ``` +
+
+
diff --git a/docs/50-aggregation/3-sort-limit.mdx b/docs/50-aggregation/3-sort-limit.mdx index a92c31a..ad2c931 100644 --- a/docs/50-aggregation/3-sort-limit.mdx +++ b/docs/50-aggregation/3-sort-limit.mdx @@ -88,7 +88,7 @@ Learn [when to use $addFields over $project](https://www.practical-mongodb-aggre ```js - db.books.aggregate([ + await books.aggregate([ { $match: { year: { $gt: 2000 } } }, @@ -108,12 +108,12 @@ Learn [when to use $addFields over $project](https://www.practical-mongodb-aggre { $limit: 1 } - ]); + ]).toArray(); ``` ```js - db.books.aggregate([ + await books.aggregate([ { $match: { year: { $gt: 2000 } } }, @@ -133,7 +133,7 @@ Learn [when to use $addFields over $project](https://www.practical-mongodb-aggre { $limit: 1 } - ]); + ]).toArray(); ``` diff --git a/docs/50-aggregation/4-group.mdx b/docs/50-aggregation/4-group.mdx index a316d85..e3abbef 100644 --- a/docs/50-aggregation/4-group.mdx +++ b/docs/50-aggregation/4-group.mdx @@ -134,14 +134,14 @@ GROUP BY year;
Answer ```js - db.reviews.aggregate([ + await reviews.aggregate([ { $group: { _id: "$_id.bookId", avgRating: { $avg: "$rating" } } } - ]); + ]).toArray(); ```
@@ -157,7 +157,7 @@ GROUP BY year; ```js - db.reviews.aggregate([ + await reviews.aggregate([ { $group: { _id: "$name", @@ -169,17 +169,17 @@ GROUP BY year; totalReviews: -1, }, }, - ]); + ]).toArray(); ``` ```js - db.reviews.aggregate([ + await reviews.aggregate([ { $sortByCount: "$name", }, - ]); + ]).toArray(); ``` diff --git a/docs/50-aggregation/5-lookup.mdx b/docs/50-aggregation/5-lookup.mdx index ee5b04a..40301ee 100644 --- a/docs/50-aggregation/5-lookup.mdx +++ b/docs/50-aggregation/5-lookup.mdx @@ -1,3 +1,6 @@ +import Tabs from "@theme/Tabs"; +import TabItem from "@theme/TabItem"; + # πŸ‘ $lookup (JOINs in MongoDB) `$lookup` in MongoDB serves a similar purpose to **JOINs** in SQL. It enables combining data from multiple collections by performing an equality match between fields. @@ -95,17 +98,43 @@ The $lookup operation creates an array within each book document. Using $unwind
Answer + + +
+ ```js + await books.aggregate([ + { + $lookup: + { + from: "reviews", + localField: "_id", + foreignField: "_id.bookId", + as: "reviews" + } + } + ]).toArray(); + ``` +
+
+ +
+ ```js + db.books.aggregate([ + { + $lookup: + { + from: "reviews", + localField: "_id", + foreignField: "_id.bookId", + as: "reviews" + } + } + ]); + ``` +
+
+
```js - db.books.aggregate([ - { - $lookup: - { - from: "reviews", - localField: "_id", - foreignField: "_id.bookId", - as: "reviews" - } - } - ]); + ```
diff --git a/docs/50-aggregation/7-merge.mdx b/docs/50-aggregation/7-merge.mdx index 8fa2bf5..ff8c83d 100644 --- a/docs/50-aggregation/7-merge.mdx +++ b/docs/50-aggregation/7-merge.mdx @@ -99,7 +99,7 @@ ON DUPLICATE KEY UPDATE totalBooks = VALUES(totalBooks); ```js - db.books.aggregate([ + await books.aggregate([ { $unwind: "$authors" }, { $group: { _id: "$authors.name", totalBooks: { $sum: 1 } } }, { @@ -110,13 +110,14 @@ ON DUPLICATE KEY UPDATE totalBooks = VALUES(totalBooks); whenNotMatched: "insert", }, }, - ]); + ]).toArray(); ``` ```js - db.authors.aggregate([ + const authors = db.collection("authors"); + await authors.aggregate([ { $unwind: "$books" }, { $group: { _id: "$name", totalBooks: { $sum: 1 } } }, { @@ -127,7 +128,7 @@ ON DUPLICATE KEY UPDATE totalBooks = VALUES(totalBooks); whenNotMatched: "insert" } } - ]); + ]).toArray(); ```