Skip to content

Commit f70e0b5

Browse files
committed
Changed SQL example to be book related
1 parent 9f79762 commit f70e0b5

File tree

2 files changed

+79
-37
lines changed

2 files changed

+79
-37
lines changed

docs/20-what-is-aggregation/2-sql-vs-aggregation.mdx

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,26 @@ A SQL query statement usually starts with a `SELECT` where we put a list of the
1010

1111
We read this from the inside. If there's too much nesting, it's not easy to follow.
1212

13+
14+
### Get authors’ bios with books that have an average 5-star rating
15+
16+
```SQL
17+
SELECT authors.name, authors.bio
18+
FROM library.authors authors
19+
JOIN library.author_book author_book_join ON authors.id = author_book_join.author_id
20+
JOIN (
21+
SELECT books.id
22+
FROM library.books books
23+
JOIN library.reviews reviews ON books.id = reviews.book_id
24+
GROUP BY books.id
25+
HAVING AVG(reviews.rating) = 5
26+
) five_star_books ON author_book_join.book_id = five_star_books.id;
27+
28+
29+
```
30+
31+
### Get annual, average and max spending from customers in all cities
32+
1333
```SQL
1434
SELECT
1535
city,
@@ -35,6 +55,44 @@ GROUP BY city;
3555

3656
## Equivalent MongoDB aggregation pipeline
3757

58+
59+
### Get authors’ bios with books that have an average 5-star rating
60+
61+
We o through 4 stages:
62+
- group all the reviews for every book, calculating the average rating.
63+
- filter out all average ratings other than 5.
64+
- now we have reviews with 5 stars, but we also want the author bio, so we join with author to get the bio.
65+
- we add a new field called `bio` with just the author's bio.
66+
67+
```js
68+
db.reviews.aggregate([
69+
{
70+
$group: {
71+
_id: "$bookId",
72+
averageRating: {
73+
$avg: "$rating",
74+
},
75+
},
76+
},
77+
{ $match: { averageRating: 5 } },
78+
{ $lookup: {
79+
from: "authors",
80+
localField: "_id",
81+
foreignField: "books",
82+
as: "author",
83+
},
84+
},
85+
{$addFields: {
86+
bio: "$author.bio"
87+
}},
88+
])
89+
90+
91+
```
92+
93+
94+
### Get annual, average and max spending from customers in all cities
95+
3896
Here we pass three stages: one to return one document per element in the `address` array, and then we filter out to get only the documents that have a `home` address location. Finally, we do the grouping. As we'll see, this can be split and tested separately and resembles our code.
3997

4098
```js

docs/20-what-is-aggregation/3-structure-aggregation.mdx

Lines changed: 21 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -20,47 +20,31 @@ db.mycollection.aggregate([
2020

2121
## Example
2222

23-
An aggregation pipeline that does the same as the above SQL statement could be:
24-
2523
```
26-
db.mycollection.aggregate([
27-
{
28-
$sort:
29-
/**
30-
* Provide any number of field/order pairs.
31-
*/
32-
{
33-
num_mflix_comments: -1,
34-
},
35-
},
36-
{
37-
$limit:
38-
/**
39-
* Provide the number of documents to limit.
40-
*/
41-
1,
42-
},
43-
{
44-
$unwind:
45-
/**
46-
* path: Path to the array field.
47-
* includeArrayIndex: Optional name for index.
48-
* preserveNullAndEmptyArrays: Optional
49-
* toggle to unwind null and empty values.
50-
*/
51-
{
52-
path: "$cast",
24+
// Inside the current database, in the collection named reviews
25+
db.reviews.aggregate([
26+
{
27+
// group all reviews for the same book
28+
$group: {
29+
_id: "$bookId",
30+
averageRating: {
31+
$avg: "$rating",
32+
},
5333
},
5434
},
55-
{
56-
$project:
57-
/**
58-
* Specifications: The fields to
59-
* include or exclude.
60-
*/
61-
{
62-
cast: 1,
35+
// filter out all reviews that have an average other than 5
36+
{ $match: { averageRating: 5 } },
37+
// JOIN with author collection to get all the author info
38+
{ $lookup: {
39+
from: "authors",
40+
localField: "_id",
41+
foreignField: "books",
42+
as: "author",
6343
},
6444
},
45+
// add a field called bio
46+
{$addFields: {
47+
bio: "$author.bio"
48+
}},
6549
])
6650
```

0 commit comments

Comments
 (0)