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

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:

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 whole collections you have a choice:

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