Skip to content

Commit b736a97

Browse files
authored
Merge pull request #44 from mongodb-developer/improve-arrays
Improve arrays
2 parents 9607909 + 56ce8cd commit b736a97

15 files changed

+1044
-283
lines changed

babel.config.js

-3
This file was deleted.

docs/1-mongodb-atlas/setup-lab.mdx

+4-2
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@ description: Setting up your MongoDB Atlas account, importing Library data
66

77
To follow along, you'll need:
88
- A MongoDB Atlas account.
9-
- Test data. In this case, this is book, author, and review data for a library management system.
9+
- Test data. In this case, this is `book`, `author`, and `review` data for a library management system.
1010

11-
👐 To get both, open the [intro lab](https://mongodb-developer.github.io/intro-lab/docs/intro) and follow it (only takes 10-15 mins) to get your database ready. Return here when finished!
11+
👐 To get this data set, open the [intro lab](https://mongodb-developer.github.io/intro-lab/docs/intro) and follow it (do only sections `MongoDB Atlas` and `Importing Data`, this should take you 10-15 mins) to get your database ready.
12+
13+
Return here when finished!

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

+58
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

+21-37
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
```
+154
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,154 @@
1+
import Tabs from '@theme/Tabs';
2+
import TabItem from '@theme/TabItem';
3+
4+
# 👐 Types of arrays
5+
6+
A JSON array can contain __simple values__ (scalar values) or __objects__. In our data, `books` have a scalar array of the `genres` this book belongs to. It also has several arrays of objects, like the `authors` of a book, `attributes` and `reviews`.
7+
8+
Let's get one book:
9+
10+
11+
<Tabs groupId="aggregations">
12+
<TabItem value="atlas" label="Atlas UI">
13+
14+
Remember to select the `books` collection in the UI.
15+
16+
```js
17+
[
18+
{ $limit: 1 }
19+
]
20+
```
21+
</TabItem>
22+
23+
<TabItem value="mongodb-shell" label="MongoDB Shell">
24+
25+
```js
26+
db.books.aggregate([
27+
{ $limit: 1 }
28+
])
29+
```
30+
</TabItem>
31+
</Tabs>
32+
33+
👐 Run this aggregation to get one book.
34+
35+
I got this one. (It can change depending on the data source you imported.)
36+
37+
```js
38+
[
39+
{
40+
"_id": "0002005018",
41+
"title": "Clara Callan: A novel",
42+
"authors": [
43+
{
44+
"_id": "64cc2db4830ba29148da4c3b",
45+
"name": "Richard Bruce Wright"
46+
}
47+
],
48+
"genres": [
49+
"Women Teachers",
50+
"Young Women",
51+
"Actresses",
52+
"Sisters"
53+
],
54+
"pages": 414,
55+
"year": 2001,
56+
"synopsis": "Giller Prize Winner 2001. Richard B. Wright. A Phyllis Bruce Book.",
57+
"cover": "https://images.isbndb.com/covers/50/12/9780002005012.jpg",
58+
"attributes": [
59+
{
60+
"key": "edition",
61+
"value": "1st"
62+
},
63+
{
64+
"key": "dimensions",
65+
"value": "Height: 11.11 Inches, Length: 6.11 Inches, Weight: 1 Pounds, Width: 1.11 Inches"
66+
},
67+
{
68+
"key": "isbn13",
69+
"value": "9780002005012"
70+
},
71+
{
72+
"key": "msrp",
73+
"value": "0.00"
74+
},
75+
{
76+
"key": "isbn",
77+
"value": "0002005018"
78+
},
79+
{
80+
"key": "isbn10",
81+
"value": "0002005018"
82+
}
83+
],
84+
"totalInventory": 2,
85+
"available": 2,
86+
"binding": "Hardcover",
87+
"language": "en",
88+
"publisher": "HarperFlamingoCanada",
89+
"longTitle": "Clara Callan: A novel",
90+
"reviews": [
91+
{
92+
"_id": {
93+
"$oid": "6526bbc2e4e804888dfedf37"
94+
},
95+
"text": "yd",
96+
"name": "Holy Dingo",
97+
"rating": 1,
98+
"timestamp": 1697037250625
99+
},
100+
{
101+
"_id": {
102+
"$oid": "651c0f4b24193d51c4c734a3"
103+
},
104+
"text": "Great!",
105+
"name": "Brash Platypus",
106+
"rating": 5,
107+
"timestamp": 1696337739128
108+
}
109+
]
110+
}
111+
]
112+
```
113+
114+
### Array of strings example
115+
116+
```json
117+
"genres": [
118+
"Women Teachers",
119+
"Young Women",
120+
"Actresses",
121+
"Sisters"
122+
],
123+
```
124+
125+
### Array of objects example
126+
127+
```json
128+
"attributes": [
129+
{
130+
"key": "edition",
131+
"value": "1st"
132+
},
133+
{
134+
"key": "dimensions",
135+
"value": "Height: 11.11 Inches, Length: 6.11 Inches, Weight: 1 Pounds, Width: 1.11 Inches"
136+
},
137+
{
138+
"key": "isbn13",
139+
"value": "9780002005012"
140+
},
141+
{
142+
"key": "msrp",
143+
"value": "0.00"
144+
},
145+
{
146+
"key": "isbn",
147+
"value": "0002005018"
148+
},
149+
{
150+
"key": "isbn10",
151+
"value": "0002005018"
152+
}
153+
],
154+
```

0 commit comments

Comments
 (0)