Mongodb Lab
Mongodb Lab
1. INTRODUCTION
• You should follow along with this tutorial by entering the commands into your
personal database, and completing the exercises where prompted.
NOTE: You should have received an email with the details for your Mongo
DB cloud account, if not then please contact [email protected] as
soon as possible to set this up. Your personal database will be the same as
your HWU username.
2. CONNECTING
You can use MongoDB Compass or Studio3D (free version), details for the setup for
each are shown below. Both are available for install on your own machine.
https://www.mongodb.com/products/tools/compass (free)
[GENERAL Tab]
HOST: 140.238.98.146:27017
[AUTHENTICATION Tab]
Click on Username/Password
Cloud-Mongo-1
2
Studio 3T Setup
Click on the CONNECT button (top left)
Click Next
[AUTHENTICATION Tab]
Click Save
3
3. CHANGE YOUR PASSWORD (OPTIONAL)
It is a good idea to change your password to something you can remember more
easily than the random password sent to you.
You’ll find it the bottom of the window, click on the words ‘>_MONGOSH’ to open it
up.
Once you’ve opened the MONGOSH (mongo shell) then switch to your database by typing:
use ab12
From here you can issue the command to change your password.
{ ok: 1 }
IMPORTANT:
You should now log out, change the connection settings to your new
password and log back in again. You’ll find the a Disconnect under the
Connect menu item.
4
If you are using Studio3T:
Issue the command to change your password from the query
window.
IMPORTANT:
You should now log out, change the connection settings
to your new password and log back in again.
5
4. IMPORTING DATA
Open a terminal on your PC
- use terminal / shell for macOS / Linux
- on Windows you can use cmd to open the command prompt
Next download the data file for this lab from the terminal using curl:
curl -o labData.json www.macs.hw.ac.uk/~pb56/labData.json
On Windows:
notepad labData.json
On mac / Linux:
cat labData.json
This is only a small file with a few records. You can see it is in JSON format and
contains some details about people such as their first_name, age, and title.
In MongoDB Compass:
Click on the + next to your username
Click Import
6
In Studio3T:
Click Create
If you are using the full version or still in the trial period you can now import the JSON file, select the
labData.json you downloaded earlier.
If you are using the free version without access to the JSON import
option then download this file using curl as you did before
www.macs.hw.ac.uk/~pb56/labData.agz then use the BSON –
mongodump archive load option instead.
Once you have loaded the dataset you should have 5 documents in your collection.
7
5. QUERYING
In MongoDB Compass:
use ab12
In Studio3T:
You can change the output view from Tree View, to Table, or JSON
8
Filtering
First of all take a look at all the data loaded, there should be 5
documents:
db.hwuPeople.find()
Notice that Manni appears in the output: mongo automatically searches inside an
array (ie the role array).
Basic queries
TASK: write a query to find all the RAs under 40 years old.
Hint: use $lt for less than.
9
Distinct
You can also find the unique values, such as distinct titles within the collection:
db.hwuPeople.distinct("title")
… which should return a list [ "dr", "mr" ] to get the number of items in the list
add .length to the previous command.
db.hwuPeople.distinct("title").length
Returned Fields
You can choose which fields in a document are returned. To display only names:
db.hwuPeople.find({},{first_name : 1, last_name : 1})
It is possible to search for strings within text fields – try this (it shouldn’t work yet!):
db.hwuPeople.find({$text: {$search: "burger"}})
The above query did not work as we have not set up a text index yet.
To create an index on the first and last names we use the command:
db.hwuPeople.createIndex({"first_name": "text","last_name": "text"})
Now we can try running that search query again and it should work this time, giving
us the list of all the people who have the string "burger" in their name.
Another way to find ‘contains’ is using regex as follows (this should also work on
non-indexed fields):
db.hwuPeople.find({"last_name":/burger/i})
You can use this query approach in conjunction with distinct – for example to find the
unique titles for people with ‘burger’ in their surname:
db.hwuPeople.distinct("title",{"last_name": /burger/i})
Note: this returns the distinct values for “title” based on the query “last_name” contains the value
‘burger’.
You can change the query to find people who have a surname starting ^ with burger or
ending $ in burger too as follows:
db.hwuPeople.distinct("first_name",{"last_name":/^burger/i})
db.hwuPeople.distinct("first_name",{"last_name":/burger$/i})
10
Multiple Conditions
You can specify multiple conditions using AND logic to add more conditions to the
query; alternatively you can specify OR to permit alternatives - for example find all
people that have a role “assistant prof” or “associate prof”:
db.hwuPeople.find({$or: [{"role": 'associate prof'}, "role": 'assistant prof'}]})
Exists
MongoDB does not enforce a schema and so each document can have different fields.
In this collection we may want to find everyone who does not have an “age”
specified:
db.hwuPeople.find({age : {$exists: false}})
Rather than listing the documents without an age, we can simply ask for the number
of documents using the count function:
db.hwuPeople.countDocuments({"age" : {$exists: false}})
AND / OR conditions
Sorting
To sort the results of a “find” query based on a field append .sort({field: 1}) after the find()
statement. Use 1 for ascending order, and -1 for descending order.
TASK: Write the query to sort the entire list of people in ascending order by age.
Aggregate / Group
If you need to get a summary for a group of values you can also sort after
aggregating, using the sortByCount function. This is like running a GROUP BY in
SQL. Here you should get the count for each title (e.g. 3 Dr,1 Dr, etc)
11
Note: The {$limit:3} is optional, here it demonstrates how you could retrieve just the top 3 groups
based on the count.
Aggregation also allows you to run calculations per group such as finding the sum,
minimum, average etc:
Inserting data
Dr Burger has been promoted and so we need to change his “title” and his “role” to
“prof”:
db.hwuPeople.update({"last_name" : "burger"}, {$set: {"title" : "prof", "role" : "prof"}})
QUESTION: What are the potential side effects of the previous statement?
HINT: “burger” is a rare last name in the UK and this is a small dataset
With a flexible schema you can add information to one document but not to others:
add an email address for Dr McLeod:
db.hwuPeople.update({"last_name": "mcleod"}, {$set: {"email": "[email protected]"}})
Look at the document for Manni:
db.hwuPeople.find({"first_name" : "manni"})
He is listed as being 37, but his birthday was last week; to increase his age:
db.hwuPeople.update({"first_name" : "manni"}, {$inc: {"age": 1}})
12
NOTE: $push only works for arrays.
TASK: update your information to provide your email address and your title
(e.g., Mr, Ms etc.).
db.hwuPeople.find({"first_name": "andy"})
Andy has not been added as no matching record was found. However, MongoDB
supports “upserts” (update or insert if there is no document found):
db.hwuPeople.update(
{ upsert: true }
);
db.hwuPeople.find({"first_name": "andy"})
13
TASK: Use the remove command to delete Joe Bloggs from the database.
HINT: most of the operations that work with the insert command also work
with the remove command.
7. OPTIMISATION
For queries to be efficient they must use an index. To check if a query uses an index
use the .explain() method:
COLLSCAN
We can see that the winning plan is COLLSCAN meaning that the collection is being
scanned, i.e. no index was used.
e.g. totalDocsExamined: 6
Now if we run the .explain() method again we see the winning plan is based on an
IXSCAN, i.e. it is using the index on the age field that we just created.
Also try the executionStats to see how many documents were examined this time.
db.hwuPeople.find({"age" : {$gt: 35}}).explain("executionStats")
e.g. totalDocsExamined: 2
14
8. BACKUP
MongoDB Compass Studio3T
Choose Export the full collection Select a format (e.g. BSON – mongodump)
9. DELETING A COLLECTION
Log into mongo and switch to your database (i.e. use ab12)
To delete the hwuPeople collection:
db.hwuPeople.drop()
10. EXERCISE
Create a new collection (called “exercise”) that includes the following
information:
name: albert burger, role: supervisor
name: alasdair gray, role: supervisor
name: iain wiles, role: phd
name: steve smith, role: phd
name: hugh dollar, role: phd
Additionally, include the following relationships:
Alasdair supervises Iain and Steve.
Albert supervises Steve and Hugh.
HINT: use an array to hold the supervisor information against
each student.
15
11. USING JAVASCRIPT WITH MONGODB
Let’s use Javascript to create 50 robots in a collection from the MonogoDB shell. We
will use a FOR loop (iteration) and the assign the value to variable i
for (i=0;i<50;i++)
{
db.robots1.insertOne({"name":"robot"+i } )
}
Count the documents in the collection to make sure it all went as planned.
db.robots1.countDocuments()
Note: you will need to type “it” to iterate through the results on MongoDB Compass; Studio3T has
page[<-][->]buttons for 50+ results
Now let’s add a unique index to the robot collection based on the name.
db.robots1.createIndex({"name":1},{unique:true})
If you try to run the Javascript again to insert the same 50 robots, you should get an
error about duplicates as a result of this unique constraint.
Comparing Collections
OK now let’s make another collection of robots numbered from 25 to 40 and this time
put them in a robot2 collection.
for (i=25;i<40;i++)
{
db.robots2.insertOne({"name":"robot"+i } )
}
We can check which robots don’t exist in both collection like this :
($nin means not in)
db.robots1.find({
});
To remove the robots from a collection use a blank search filter like this:
db.robots1.deleteMany({})
16