MongoDB Tutorial
Having learned how to install and log in into MongoDB, we go on to manage our databases:
Handling DataBases
Finding Which Database(s) you are Using
Currently
After connecting to your database using mongosh
, you can see which database you are using by typing db
in your terminal.
If you have used the connection string provided from the MongoDB Atlas dashboard, you should be connected to the myFirstDatabase database.
Collections in MongoDB
A collection is a set of JSON objects, and is analogous to a table in a relational database.
-
To create a collection issue:
db.createCollection("myCollection")
-
To insert data into a (possibly non-existent) collection issue:
db.myCollection.insert({"name": "john", "age" : 22, "location": "colombo"})
Show all Databases or all Collections
To see all available databases, in your terminal type show databases
or show dbs
.
To see all available collections, in your terminal type show collections
or show tables
.
Notice that myFirstDatabase is not listed. This is because the database is empty. An empty database is essentially non-existant.
Change or Create a Database or Create a Collection
You can change or create a new database by typing use
then the name of the database.
Example
Create a new database called blog:
use blog
We are now in the blog database.
If database blog already existed, then use blog
would just change into database blog.
Remember: In MongoDB, a database is not actually created until it gets content!
Inserting (Objects) in MongoDB
-
To insert one data item in a collection issue:
>db.myCollection.insertOne( { "name": "navindu", "age": 22 } )
-
To insert several comma-separated data items in a collection issue:
db.myCollection.insertMany([ { "name": "navindu", "age": 22 }, { "name": "kavindu", "age": 20 }, { "name": "john doe", "age": 25, "location": "colombo" } ])
- The
insert()
method is similar to theinsertMany()
method.
Special Index and Collection Types*
Introduction to the Aggregation Framework*
Updating Documents
To update one or several documents we often rely on $set
. Actually, we construct an object where $set
is the key and the intended values are $set
's value, as in:
{$set: {"my_key": my_value}
Updating documents can be done in three ways in MongoDB:
update()
: updates one or many documents matching the criteria, based on the value set for the boolean parameter multi. If multi isfalse
, the query updates only one record.updateOne()
: updates the first document found with the matching criteriaupdateMany()
: updates all the documents that match the specified criteria
A very simple example
To update someone's age issue: db.myCollection.update({age : 20}, {$set: {age: 23}})
A worked example
Suppose we want to update the exam score to 35 in some document that we inserted above. The query is as follows:
db.grades.updateOne({_id: 1, "scores.type": 'exam'},\
{$set:{'scores.$.score': 35}})
Note that the scores field is an array/object, so we use the dot operator to access the fields. To update the value, we need to use the positional operator ($
). If the document is updated successfully, you will get an acknowledgement:
{ acknowledged: true, insertedId: null, matchedCount: 1, modifiedCount: 1, upsertedCount: 0 }
Note the parameter upsertedCount. MongoDB uses an optional parameter known as ‘upsert', the value of which can be a boolean (true/false). While writing the update query, if upsert is set to true, the document is inserted if it doesn't exist.
An example with upset set to true
For example, let's try to update a document with _id as 10000 (which doesn't exist), with upsert as true
:
db.grades.update( { student_id: 10000 }, { $set: { class_id: 180, "scores.type": "exam", "scores.score" : 50 } }, { upsert: true } )
Operator $unset
The $unset
operator is the exact opposite of the $set
operator. Rather than assigning a new value to a field, the $unset operator will give an empty value to a field thereby deleting it. Here's an example of the $unset
operator,
db.grades.update({_id: 1}, {$unset: {"scores.score": ""}}),\
whereby scores.score is removed for object with _id equal to 1.
Operator $inc
The $inc
operator is MongoDB's abbreviation of increment
, an operator designed to increase or decrease the value of a field. $inc
can be used with either floats or integers, which means that decimal values can be passed through $inc
without an issue. Here's an example of the $inc
operator with an integer.
db.grades.update({_id: 111}, {$inc: {"scores.score": -1}}),\
Here the value of scores.score is decreased by one. For example, if its value was previously 10, now it would be 9.
Operator $push
The $push
operator can push a new element to an array field or modify an existing element. Elements are similar to values in a list and are held in a specific field.
An example
Modifiers
In MongoDB there are four modifiers, $each
, $position
, $slice
, and $sort
. These all modify the functionality of the $push
operator to help with organization or efficiency. While these modifiers are not required when performing an update on a document, they play a key role in simplifying the updating process.
$each
The $each
modifier can be used with $push
or $addToSet
to select multiple items to append to a field. Rather than copying a previous $push command and complicating the query, the $each modifier allows users to seamlessly execute multiple $push commands.
$position
The $position
modifier allows users to specify where in an array an item should be appended. In fields where proper ordering is crucial, the $position
modifier is a simple solution to any issues with item placement.
$slice
The $slice
modifier performs a similar function to the $limit
operator in the aggregation pipeline; it reduces the total documents to a finite number. The $slice
operator allows users to create a new limit in the updated collection which will be executed alongside any other updates.
$sort
The $sort
modifier allows users to rearrange documents according to a given metric/field. For example, if a user wanted to arrange a list of books in order of publish date, the $sort modifier would allow them to do so.
$bit
The $bit
operator is unique because it modifies the individual bits of a field. $bit uses bitwise functions such as AND
, OR
, and XOR
to create conditionals for which bits it chooses to modify. $bit is a highly technical operator with limited uses in most day-to-day queries.
Operator $pull
The $pull
operator is the opposite of the $push
operator. It removes one element from an array field or, if there is only one element left in the array, deletes the entire field from a document.
Deleting/Removing Documents
Analogously to other operations, MongoDB provides deleteOne()
and deleteMany()
options.
Some common cases:
- To remove a document fulfilling a simple key-value condition, issue:
db.myCollection.remove({name: "navindu"});
- To remove just a property (i.e. a key-value pair), issue:
db.myCollection.update({name: "navindu"}, {$unset: age});
To remove whole collections you have a choice:
- To remove a whole collection, issue:
db.myCollection.remove({});
. - To remove all the documents in a collection, issue:
db.myCollection.drop();
.
Outputing to and Inputing from a File
You can log all the shell session if you invoked the shell with tee command: mongo | tee session.txt
. Or you can use the --eval
switch like so: mongo localhost:27017/dbname --eval "printjson(db.MyCollection.find().pretty())" > sample.json
.
Outputing to a File with mongoexport
- To get all documents in collection crops, in database farming, into file
farming.crops.json , issue:mongoexport --db=farming --collection=crops --out="farming.crops.json" --pretty
- To get results as an array, add
--jsonArray
, as in:mongoexport --db=farming --collection=crops --out="farming.crops.json" --pretty --jsonArray
- You can select which fields to get through
-f, --fields=<field>[,<field>]*
(a comma separated list of field names (required for exporting CSV) e.g. -f "name,age") or--fieldFile=<filename>
(a file with field names, one per line) - You can specify a query filter through
-q, --query=<json>
, such as{x:{$gt:1}}
, or set a path to a query file containing a query filter for JSON files, through--queryFile=<filename>
MongoDB Schema Validation
By default MongoDB has a flexible schema, unlike Relational DataBases. This means that there is no strict schema validation set up initially.
Schema validation rules can be created in order to ensure that all documents in a collection share a similar structure.
MongoDB supports JSON Schema validation. The $jsonSchema
operator allows us to define our document structure.
db.createCollection("posts", { validator: { $jsonSchema: { bsonType: "object", required: [ "title", "body" ], properties: { title: { bsonType: "string", description: "Title of post - Required." }, body: { bsonType: "string", description: "Body of post - Required." }, category: { bsonType: "string", description: "Category of post - Optional." }, likes: { bsonType: "int", description: "Post like count. Must be an integer - Optional." }, tags: { bsonType: ["string"], description: "Must be an array of strings - Optional." }, date: { bsonType: "date", description: "Must be a date - Optional." } } } } })
This will create the posts collection in the current database and specify the JSON Schema validation requirements for the collection.
Inputing from a File with mongoimport
Switches --db
, --collections
, --fields
, --fieldFile
, --jsonArray
are the same as with mongoexport
.
Command mongoimport
has some ingest switches, too:
-
--drop
- drop collection before inserting documents
-
--ignoreBlanks
- ignore fields with empty values in CSV and TSV
-
--maintainInsertionOrder
- insert documents in the order of their appearance in the input source
-
-j, --numInsertionWorkers=<number>
- number of insert operations to run concurrently (defaults to 1) (default: 1)
-
--stopOnError
- stop importing at first insert/upsert error
-
--mode=[insert|upsert|merge]
- insert: insert only; upsert: insert or replace existing documents; merge: insert or modify existing documents; defaults to insert
-
--upsertFields=<field>[,<field>]*
- comma-separated fields for the query part when --mode is set to upsert or merge
-
--writeConcern=<write-concern-specifier>
- write concern options e.g. --writeConcern majority, --writeConcern '{w: 3, wtimeout: 500, fsync: true, j: true}'
-
--bypassDocumentValidation
- bypass document validation