Skip to content

Commit 88ebfe3

Browse files
Fixed aggregation exercises
1 parent cfcdbb2 commit 88ebfe3

10 files changed

+232
-59
lines changed

β€Ždocs/10-intro.mdx

+3-4
Original file line numberDiff line numberDiff line change
@@ -7,16 +7,15 @@ sidebar_position: 0
77
import Tabs from "@theme/Tabs";
88
import TabItem from "@theme/TabItem";
99

10-
| Lab goals | Learn about aggregation pipelines writing aggregation pipelines |
10+
| Lab goals | Learn about MongoDB's Query API including Aggregation Framework |
1111
| ----------------- | ----------------------------------------------------------------------------------- |
12-
| What you'll learn | What are aggregation pipelines? |
13-
| | How are they different from simple MongoDB queries or SQL? |
12+
| What you'll learn | CRUD Operations in MongoDB vs SQL |
13+
| | Aggregation Framework in MongoDB |
1414
| | How to use simple pipelines to get data, filter it, show the fields needed |
1515
| | How to write more advanced pipelines, querying arrays, counting and sorting results |
1616
| | How to do JOINs using $lookup |
1717
| | How to group data |
1818
| | Exporting data |
19-
| | How to write aggregations using popular programming languages (TBD) |
2019
| Time to complete | 90 mins |
2120

2221
In the navigation bar and on some pages, you will notice some icons. Here are their meanings:

β€Ždocs/40-CRUD/2-SELECT.mdx

+23-9
Original file line numberDiff line numberDiff line change
@@ -71,12 +71,26 @@ Here:
7171

7272
---
7373

74-
## **Exercises**
75-
76-
πŸ‘ **Retrieve only the `title` field for all books.**
77-
πŸ‘ **Fetch only `title` and `totalInventory` for books with more than 500 pages.**
78-
πŸ‘ **Retrieve all fields except `_id` and `authors` for books in the "History" genre.**
79-
πŸ‘ **Find all books written by "Isaac Asimov" and return only `title` and `available` copies.**
80-
πŸ‘ **Exclude `reviews` and `attributes` from the query results.**
81-
82-
---
74+
## **Challenge**
75+
76+
### πŸ‘ 1. Retrieve only the `title` field for all books.
77+
78+
<details>
79+
<summary>Answer</summary>
80+
<div>
81+
```js
82+
db.books.find({}, {title: 1, _id: 0});
83+
```
84+
</div>
85+
</details>
86+
87+
### πŸ‘ 2. Retrieve all fields except `_id` and `authors` for books in the "History" genre.
88+
89+
<details>
90+
<summary>Answer</summary>
91+
<div>
92+
```js
93+
db.books.find({genres: "History"}, {_id: 0, authors: 0});
94+
```
95+
</div>
96+
</details>

β€Ždocs/40-CRUD/3-ORDER-BY-SORT.mdx renamed to β€Ždocs/40-CRUD/3-ORDER-LIMIT.mdx

+12-7
Original file line numberDiff line numberDiff line change
@@ -58,10 +58,15 @@ This returns the **top 10 available books** in the "Science Fiction" genre.
5858

5959
---
6060

61-
## **Exercises**
62-
63-
πŸ‘ Retrieve the top 3 books with the most reviews.
64-
πŸ‘ Find the **first 10 books** alphabetically by `title`.
65-
πŸ‘ Get the **latest 5 books** added to the database (assume a `createdAt` field).
66-
πŸ‘ Find **the 2 oldest authors** (assume a `birthYear` field).
67-
πŸ‘ Retrieve **the top 7 books** with the highest `rating`.
61+
## Challenge
62+
63+
### πŸ‘ 1. Find the first 10 books alphabetically by `title`.
64+
65+
<details>
66+
<summary>Answer</summary>
67+
<div>
68+
```js
69+
db.books.find({}).sort({title: 1}).limit(10)
70+
```
71+
</div>
72+
</details>

β€Ždocs/40-CRUD/4-INSERT-DELETE.mdx

+48-4
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,51 @@ db.reviews.deleteOne({
6161
DELETE FROM reviews WHERE bookId = '0786222727';
6262
```
6363

64-
## Exercises
65-
66-
- πŸ‘ Insert 4 more reviews for `bookId` "0786222727".
67-
- πŸ‘ Delete all the reviews for `bookId` "0786222727" through a single command.
64+
## Challenge
65+
66+
### πŸ‘ 1. Insert 4 more reviews for `bookId` "0786222727".
67+
68+
<details>
69+
<summary>Answer</summary>
70+
<div>
71+
```js
72+
db.books.insertMany([
73+
{
74+
text: "Thrilling end.",
75+
rating: 4,
76+
name: "Mark",
77+
bookId: "0786222727",
78+
},
79+
{
80+
text: "Must read!",
81+
rating: 5,
82+
name: "Raj",
83+
bookId: "0786222727",
84+
},
85+
{
86+
text: "Very expensive",
87+
rating: 3,
88+
name: "Yun",
89+
bookId: "0786222727",
90+
},
91+
{
92+
text: "Extremely satisfied with the storyline!",
93+
rating: 5,
94+
name: "Lisa",
95+
bookId: "0786222727",
96+
}
97+
]);
98+
```
99+
</div>
100+
</details>
101+
102+
### πŸ‘ 2. Delete all the reviews for `bookId` "0786222727" through a single command.
103+
104+
<details>
105+
<summary>Answer</summary>
106+
<div>
107+
```js
108+
db.books.deleteMany({"bookId": "0786222727"})
109+
```
110+
</div>
111+
</details>

β€Ždocs/40-CRUD/5-UPDATE.mdx

+15-5
Original file line numberDiff line numberDiff line change
@@ -76,8 +76,18 @@ Executing the above command, will insert a fresh new document in the collection
7676

7777
---
7878

79-
## Exercises
80-
81-
- πŸ‘ Update the pages of "NoSQL Guide" to 450.
82-
- πŸ‘ Update all books published before 2000 to have isClassic: true.
83-
- πŸ‘ What happens if no document matches the update query?
79+
## Challenge
80+
81+
### πŸ‘ 1. Update the pages of the book "Treasure of the Sun" to 449.
82+
83+
<details>
84+
<summary>Answer</summary>
85+
<div>
86+
```js
87+
db.books.updateOne(
88+
{"title": "Treasure of the Sun"},
89+
{$set: {pages: 449}}
90+
);
91+
```
92+
</div>
93+
</details>

β€Ždocs/50-aggregation/2-match-project.mdx

+28-9
Original file line numberDiff line numberDiff line change
@@ -90,12 +90,31 @@ db.books.aggregate([
9090

9191
---
9292

93-
### **Exercise πŸš€**
94-
95-
πŸ‘ Find books with more than 10 available copies.
96-
πŸ‘ Return only book titles and publication year.
97-
πŸ‘ Create a computed field `stockStatus`: "In Stock" if available > 0, otherwise "Out of Stock".
98-
99-
---
100-
101-
πŸ”Ή **Next Up: Understanding $group and $sort!**
93+
## Challenge πŸš€
94+
95+
### πŸ‘ 1. Find books with more than 2 available copies.
96+
97+
<details>
98+
<summary>Answer</summary>
99+
<div>
100+
```js
101+
db.books.aggregate([
102+
{ $match: {available: {$gt: 2}}}
103+
]);
104+
```
105+
</div>
106+
</details>
107+
108+
### πŸ‘ 2. Find books with more than 2 available copies, return only book titles and publication year.
109+
110+
<details>
111+
<summary>Answer</summary>
112+
<div>
113+
```js
114+
db.books.aggregate([
115+
{ $match: {available: {$gt: 2}}},
116+
{ $project: {title: 1, year: 1, _id: 0}}
117+
]);
118+
```
119+
</div>
120+
</details>

β€Ždocs/50-aggregation/3-sort-limit.mdx

+3-1
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,9 @@ SELECT * FROM books ORDER BY timestamp DESC LIMIT 5;
6767

6868
---
6969

70-
### πŸ‘ Challenge: After the year 2010, which book has the most number of authors.
70+
### πŸ‘ Challenge
71+
72+
## πŸ‘ 1. After the year 2010, which book has the most number of authors.
7173

7274
<details>
7375
<summary>Answer</summary>

β€Ždocs/50-aggregation/4-GROUP-BY.mdx renamed to β€Ždocs/50-aggregation/4-group.mdx

+59-5
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
1+
import Tabs from "@theme/Tabs";
2+
import TabItem from "@theme/TabItem";
3+
14
# πŸ‘ $group
25

36
In SQL, the GROUP BY statement groups rows that have the same values into summary rows, like "find the number of customers in each country".
@@ -118,8 +121,59 @@ GROUP BY bookId;
118121

119122
---
120123

121-
## πŸ‘ Exercise
122-
123-
πŸ‘ Find the total number of reviews each book has received.
124-
πŸ‘ Get the highest rating given to each book.
125-
πŸ‘ Count the number of authors who have written at least one book.
124+
## πŸ‘ Challenge
125+
126+
### πŸ‘ 1. Find the total number of pages published every year.
127+
128+
<details>
129+
<summary>Answer</summary>
130+
```js
131+
db.books.aggregate([
132+
{
133+
$group: {
134+
_id: "$year",
135+
totalPages: { $sum: "$pages" }
136+
}
137+
},
138+
]);
139+
```
140+
</details>
141+
142+
### πŸ‘ 2. Find users with the most number of reviews. Hint: Use the `name` field in the reviews collection.
143+
144+
<details>
145+
<summary>Answer</summary>
146+
There are 2 ways to solve this-
147+
- $group with $sort
148+
- $sortByCount
149+
<Tabs groupId="aggregations">
150+
<TabItem value="atlas" label="$group with $sum + $sort">
151+
```js
152+
db.reviews.aggregate([
153+
{
154+
$group: {
155+
_id: "$name",
156+
totalReviews: { $sum: 1 },
157+
},
158+
},
159+
{
160+
$sort: {
161+
totalReviews: -1,
162+
},
163+
},
164+
]);
165+
```
166+
</TabItem>
167+
168+
<TabItem value="mongodb-shell" label="$sortByCount">
169+
```js
170+
db.reviews.aggregate([
171+
{
172+
$sortByCount: "$name",
173+
},
174+
]);
175+
```
176+
</TabItem>
177+
178+
</Tabs>
179+
</details>

β€Ždocs/50-aggregation/5-JOIN.mdx

+24-9
Original file line numberDiff line numberDiff line change
@@ -30,9 +30,9 @@ The `$lookup` stage is used to fetch related documents from another collection,
3030

3131
## πŸ”Ή Joining 2 collections
3232

33-
### πŸ‘ Example 1: Joining Authors collection with Books\*\*
33+
### πŸ‘ Example 1: Joining Authors collection with Books
3434

35-
πŸ” **Get book details along with their authors**
35+
πŸ” Get book details along with their authors
3636

3737
```js
3838
db.authors.aggregate([
@@ -65,7 +65,7 @@ The result in MongoDB will have an array (`authorDetails`) instead of flat colum
6565

6666
Since `$lookup` produces an **array**, we can flatten it using `$unwind`.
6767

68-
### Example 2: Get Book Titles and Single Author Name
68+
### Example 2: Get Only Book Titles and Single Author Name
6969

7070
```js
7171
db.authors.aggregate([
@@ -83,13 +83,28 @@ db.authors.aggregate([
8383
```
8484

8585
:::info
86-
The $lookup operation creates an array within each book document. Using $unwind then flattens this array, resulting in a separate document for every book and each author.
86+
The $lookup operation creates an array within each book document. Using $unwind then flattens this array, resulting in a separate document for every single book - author pair.
8787
:::
8888

8989
---
9090

91-
## **πŸš€ Exercise**
92-
93-
πŸ‘ Fetch books with their associated reviews.
94-
πŸ‘ Get authors and the books they have written.
95-
πŸ‘ Use `$unwind` to show each book-author pair separately.
91+
## πŸ‘ Challenge
92+
93+
### πŸ‘ 1. Fetch books with their associated reviews
94+
95+
<details>
96+
<summary>Answer</summary>
97+
```js
98+
db.books.aggregate([
99+
{
100+
$lookup:
101+
{
102+
from: "reviews",
103+
localField: "_id",
104+
foreignField: "bookId",
105+
as: "reviews"
106+
}
107+
}
108+
]);
109+
```
110+
</details>

β€Ždocs/50-aggregation/7-CREATE-VIEW.mdx

+17-6
Original file line numberDiff line numberDiff line change
@@ -102,12 +102,23 @@ ON DUPLICATE KEY UPDATE totalBooks = VALUES(totalBooks);
102102

103103
---
104104

105-
## **πŸ”Ή Exercise πŸš€**
105+
## πŸ‘ Challenge
106106

107107
πŸ‘ Create a `top_rated_books` collection that stores books with an average rating above 4.5.
108-
πŸ‘ Maintain a `review_stats` collection that contains the total number of reviews per book.
109-
πŸ‘ Update the `borrowed_books_summary` collection by storing the total borrowed count for each book.
110108

111-
---
112-
113-
πŸš€ **Next Up: Optimizing Aggregation Pipelines!**
109+
<details>
110+
<summary>Answer</summary>
111+
```js
112+
db.books.aggregate([
113+
{
114+
$lookup:
115+
{
116+
from: "reviews",
117+
localField: "_id",
118+
foreignField: "bookId",
119+
as: "reviews"
120+
}
121+
}
122+
]);
123+
```
124+
</details>

0 commit comments

Comments
Β (0)