You are on page 1of 10

// -- Aggregation & Relations

// Aggregation

// 1- insert the following documents into a collection, then query to check your
result
/*
[
{"name": "Seoul", "country": "South Korea", "continent": "Asia", "population":
25.674 },
{"name": "Mumbai", "country": "India", "continent": "Asia", "population":
19.980 },
{"name": "Lagos", "country": "Nigeria", "continent": "Africa", "population":
13.463 },
{"name": "Beijing", "country": "China", "continent": "Asia", "population":
19.618 },
{"name": "Shanghai", "country": "China", "continent": "Asia", "population":
25.582 },
{"name": "Osaka", "country": "Japan", "continent": "Asia", "population": 19.281
},
{"name": "Cairo", "country": "Egypt", "continent": "Africa", "population":
20.076 },
{"name": "Tokyo", "country": "Japan", "continent": "Asia", "population": 37.400
},
{"name": "Karachi", "country": "Pakistan", "continent": "Asia", "population":
15.400 },
{"name": "Dhaka", "country": "Bangladesh", "continent": "Asia", "population":
19.578 },
{"name": "Rio de Janeiro", "country": "Brazil", "continent": "South America",
"population": 13.293 },
{"name": "São Paulo", "country": "Brazil", "continent": "South America",
"population": 21.650 },
{"name": "Mexico City", "country": "Mexico", "continent": "North America",
"population": 21.581 },
{"name": "Delhi", "country": "India", "continent": "Asia", "population": 28.514
},
{"name": "Buenos Aires", "country": "Argentina", "continent": "South America",
"population": 14.967 },
{"name": "Kolkata", "country": "India", "continent": "Asia", "population":
14.681 },
{"name": "New York", "country": "United States", "continent": "North America",
"population": 18.819 },
{"name": "Manila", "country": "Philippines", "continent": "Asia", "population":
13.482 },
{"name": "Chongqing", "country": "China", "continent": "Asia", "population":
14.838 },
{"name": "Istanbul", "country": "Turkey", "continent": "Europe", "population":
14.751 }
]
*/
>>> use israadb
db.city.insertMany([
{"name": "Seoul", "country": "South Korea", "continent": "Asia", "population":
25.674 },
{"name": "Mumbai", "country": "India", "continent": "Asia", "population":
19.980 },
{"name": "Lagos", "country": "Nigeria", "continent": "Africa", "population":
13.463 },
{"name": "Beijing", "country": "China", "continent": "Asia", "population":
19.618 },
{"name": "Shanghai", "country": "China", "continent": "Asia", "population":
25.582 },
{"name": "Osaka", "country": "Japan", "continent": "Asia", "population": 19.281
},
{"name": "Cairo", "country": "Egypt", "continent": "Africa", "population":
20.076 },
{"name": "Tokyo", "country": "Japan", "continent": "Asia", "population": 37.400
},
{"name": "Karachi", "country": "Pakistan", "continent": "Asia", "population":
15.400 },
{"name": "Dhaka", "country": "Bangladesh", "continent": "Asia", "population":
19.578 },
{"name": "Rio de Janeiro", "country": "Brazil", "continent": "South America",
"population": 13.293 },
{"name": "São Paulo", "country": "Brazil", "continent": "South America",
"population": 21.650 },
{"name": "Mexico City", "country": "Mexico", "continent": "North America",
"population": 21.581 },
{"name": "Delhi", "country": "India", "continent": "Asia", "population": 28.514
},
{"name": "Buenos Aires", "country": "Argentina", "continent": "South America",
"population": 14.967 },
{"name": "Kolkata", "country": "India", "continent": "Asia", "population":
14.681 },
{"name": "New York", "country": "United States", "continent": "North America",
"population": 18.819 },
{"name": "Manila", "country": "Philippines", "continent": "Asia", "population":
13.482 },
{"name": "Chongqing", "country": "China", "continent": "Asia", "population":
14.838 },
{"name": "Istanbul", "country": "Turkey", "continent": "Europe", "population":
14.751 }
])

// 2- get the data for the North America continent only

1) db.city.find({continent:"North America"},{})
2) db.city.aggregate([
{$match: {continent:"North America"}}
])

// 3- get the data for the North America, or Asia continent using two different
methods
1)
db.city.find({$or:[{continent:"North America"},{continent:"Asia"}]})
db.city.find({continent:{$in:["North America","Asia"]}})
2)
db.city.aggregate(
[
{ $match: { $or: [ { continent: "North America" }, { continent: "Asia" } ] } }
]
)
db.city.aggregate(
[
{ $match: {continent:{$in:["North America","Asia"]}} }
]
)

// 4- sort the data in descending order according to the number of population

1)db.city.find().sort({population:-1})
2)db.city.aggregate(
[
{$sort: {population:-1} }
]
)
// 5- sort the data in ascending order according to the number of population for
North America continent

1)db.city.find({continent:"North America"}).sort({population:-1})
2)db.city.aggregate(
[
{$match: {continent:"North America"} } ,
{$sort: {population:-1} }
]
)
// 6- get the distinct continent using two different methods
1) db.city.aggregate(
[
{$group: {_id:"$continent"} }

]
)
2)
db.city.distinct("continent")

// 7- get the distinct continent-country


db.city.aggregate(
[
{$group: {_id:["$continent","$country"]} }

]
)
db.city.aggregate(
[
{$group: {_id:{continent:"$continent",country:"$country"} }}

]
)

// 8- get max number of population per continent-country, and count the number of
cites per continent-country
db.city.aggregate(
[
{$group: {_id:{continent:"$continent",country:"$country"},maxPopulation:
{$max:"$population"} ,countCity:{$sum:1}}}

]
)
// 9- view the document in that format { "location" : { "country" : "South Korea",
"continent" : "Asia" }, "name" : "Seoul", "population" : 25.674 }

db.city.aggregate([
{
$project: {
_id: 0,
name: 1,
population: 1,
location: {
country: "$country",
continent: "$continent"
}

}
}
])
// 10- find the most populated city for each continent-country Asia and North
America and return both its name and population. The results should be sorted by
the highest population, and you are interested only in countries where the most
populated city crosses the threshold of 20 million people
db.city.aggregate(
[{$match: {$or: [{ continent: "North America" },{ continent: "Asia" }],population:
{ $gte: 20 }}},
{ $sort: { population: -1 } },
{ $project: { name: 1, population: 1, _id: 0 } }
])

// 11- modify your last query to make the result look like the following:
/*
"location" : {
"country" : "Japan",
"continent" : "Asia"
},
"most_populated_city" : {
"name" : "Tokyo",
"population" : 37.4
}
}
*/
db.city.aggregate([
{$match: {$or: [{ continent: "North America"}, { continent: "Asia" }] } },{$sort:
{population:-1} },
{$project: {
_id: 0,
location: { country: "$country", continent: "$continent" },
most_populated_city: { name: "$name", population: "$population" }} }
])

//
----------------------------------------------------------------------------------
// Relations

/*
12- Authors, and Books have a Many-To-Many relationship, also Book and Genres have
a Many-To-Many relationship given the data as the following:
authors:
id,name,birth_date,popularity
1,author1,birth_date1,popularity1
2,author2,birth_date2,popularity2
3,author3,birth_date3,popularity3
4,author4,birth_date4,popularity4

books:
id,title,release_date,price,rating
1,title1,release_date_1,101,1
2,title2,release_date_2,102,2
3,title3,release_date_3,103,3
4,title4,release_date_4,104,4

genres
id,name
1,drama
2,crime
3,animated

author_book
author_id, book_id
1,1
1,2
1,3
2,1
3,2
2,3
3,4
4,4

genre_book
genre_id,book_id
1,1
1,2
1,3
1,4
2,1
2,2
3,1

- show how you can model it in MongoDB by creating your collections, and explain
why did you choose that model
- in many cases queries uses these fields to answer questions:
name of the author, title of the book, and name of the genre

>>
1) since the genres collection has only id , name and each book can't have a lot of
genres
we can delete the genres collection and add the genres directly to book collection.
2) since each book has few authors ,but each author has a lot of books we can add
the author id to the books collection and delete the
author_book collection , and we can also add the name of the author to the books
because a lot of queries need the name of the author.
3) so we now have only 2 collections:
>> 1) Authors collection
db.authors.insertMany([
{
"id": 1,
"name": "author1",
"birth_date": "birth_date1",
"popularity": "popularity1"
},
{
"id": 2,
"name": "author2",
"birth_date": "birth_date2",
"popularity": "popularity2"
},
{
"id": 3,
"name": "author3",
"birth_date": "birth_date3",
"popularity": "popularity3"
},
{
"id": 4,
"name": "author4",
"birth_date": "birth_date4",
"popularity": "popularity4"
}
]);
>> 2) Books collection:
db.books.insertMany([
{
"id": 1,
"title": "title1",
"release_date": "release_date_1",
"price": 101,
"rating": 1,
"authors": [
{
"id": 1,
"name": "author1"
},
{
"id": 2,
"name": "author2"
}
],
"genres": ["drama", "crime", "animated"]
},
{
"id": 2,
"title": "title2",
"release_date": "release_date_2",
"price": 102,
"rating": 2,
"authors": [
{
"id": 1,
"name": "author1"
},
{
"id": 3,
"name": "author3"
}
],
"genres": ["drama", "crime"]
},
{
"id": 3,
"title": "title3",
"release_date": "release_date_3",
"price": 103,
"rating": 3,
"authors": [
{
"id": 1,
"name": "author1"
},
{
"id": 2,
"name": "author2"
}
],
"genres": ["drama"]
},
{
"id": 4,
"title": "title4",
"release_date": "release_date_4",
"price": 104,
"rating": 4,
"authors": [
{
"id": 3,
"name": "author3"
},
{
"id": 4,
"name": "author4"
}
],
"genres": ["drama"]
}
]);

- write queries that answer the following questions:


*who are the authors of the book "title1" ?
>> db.books.find({ "title": "title1" }, { "authors.name": 1,_id: 0})
*what are the books written by "author1" ?
>> db.books.find({ "authors.name": "author1" }, { "title": 1,_id: 0 })

*what are the genres of the book "title2" ?


>> db.books.find({ title: "title2" },{ genres: 1,_id: 0 })
*what are the books that have "crime" genre ?
>> db.books.find({ genres: "crime" }, { title: 1,_id: 0 })
*who are the authors that have books with "animated" genre?
>> db.books.find({ genres: "animated" },{ "authors.name": 1, _id: 0 })
- what if the genres data was like that:
genres
id,name,description,popularity
1,drama,description1,popularity1
2,crime,description2,popularity2
3,animated,description3,popularity3
- give your thought about what might change in your data modeling (your model
may not need to change) however you still need to give your thoughts why you are
not going to change it
*/
>> Now , we have additional information about genres it will be too large to be
added to books collection
>> also , most of queries need the name of genre only
so we aill create a new collection for genres and we will modify the books
collection to have the id of the genres in addition to the name
to enhance the query perfomance and minimize the join operations to get the name of
the genres which will serve our queries well.
>> Genres Collection:
db.genres.insertMany([
{ id: 1, name: "drama", description: "description1", popularity: "popularity1" },
{ id: 2, name: "crime", description: "description2", popularity: "popularity2" },
{ id: 3, name: "animated", description: "description3", popularity: "popularity3"
}
]);
>> Books:
db.books.insertMany([
{
"id": 1,
"title": "title1",
"release_date": "release_date_1",
"price": 101,
"rating": 1,
"authors": [
{
"id": 1,
"name": "author1"
},
{
"id": 2,
"name": "author2"
}
],
"genres": [
{
"id": 1,
"name": "drama"
},
{
"id": 2,
"name": "crime"
},
{
"id": 3,
"name": "animated"
}
]
},
{
"id": 2,
"title": "title2",
"release_date": "release_date_2",
"price": 102,
"rating": 2,
"authors": [
{
"id": 1,
"name": "author1"
},
{
"id": 3,
"name": "author3"
}
],
"genres": [
{
"id": 1,
"name": "drama"
},
{
"id": 2,
"name": "crime"
}
]
},
{
"id": 3,
"title": "title3",
"release_date": "release_date_3",
"price": 103,
"rating": 3,
"authors": [
{
"id": 1,
"name": "author1"
},
{
"id": 2,
"name": "author2"
}
],
"genres": [
{
"id": 1,
"name": "drama"
}
]
},
{
"id": 4,
"title": "title4",
"release_date": "release_date_4",
"price": 104,
"rating": 4,
"authors": [
{
"id": 3,
"name": "author3"
},
{
"id": 4,
"name": "author4"
}
],
"genres": [
{
"id": 1,
"name": "drama"
}
]
}
]);

You might also like