MongoDB Beginner Notes

Source: MongoDB Tutorial for Beginners

Intro

First distinction:

MongoDB is a NoSQL database. It has no relations, but binary json files not related to each other (BSON). Here are its main characteristics:

Download and Install

brew install MongoDB

or

manually download from website
unzip and place the extracted folder (maybe renamed) in <mongodir>
add <mongodir>/bin to $PATH
create <datadir> (default: /data/db, can be customized for instance to <mongodir>/data/db)
    if custom <datadir>, alias mongod --dbpath <customdatadir>

GUIs for MongoDB:

Database structure

database -> collections -> documents -> fields

Basic Instructions

Create Database

use <dbname>

If dbname is already present, switch to it. Otherwise create it, then switch to it.

See current working db

db

Note: db is the alias for the database we are using!

List all databases

show dbs 

Only databases with at least some data are displayed.

Insert documents

db.<mycollection>.insert([key-value-pairs])
# where
[key-value-pairs] = {"name":"Max"}  # json-like!

Drop / Delete db

use <db_to_drop>
db.dropDatabase()

Create collection

db.createCollection("mycollection", [maybe options])

Creates an empty collection named “mycollection” in the current db.

db.mycollection2.insert({"name":"max"})

If collection “mycollection2” is not present, creates it. Then, insert the document.

See collections in the current db

show collections

It lists “mycollection” (empty) and “mycollection2” (having 1 document).

Drop collections

db.mycollection.drop()

Collection “mycollection” gets dropped.

Insert documents into databases

School database example:

To insert a single document:

use school
db.createCollection("students")
db.students.insert(
    {
        "name":"max",
        "surname":"reds",
        "age":"10"
    }
)

Everything in the curly brackets is ONE DOCUMENT (aka a json element).

Each document has key-value pairs related to the very same student.

We have one document, with several fields, for each student.

The group of students is the “collection” (collection of documents).

To insert multiple documents at once:

db.students.insert([
    {
        "name":"lou",
        "surname":"greens",
        "age":"11"
    },
    {
        "name":"william",
        "surname":"yellows",
        "age":"10"
    },
    {...}
])

Same as before, but add square brackets; separate documents with comma.

Note: when a document is inserted, MongoDB creates a unique identifier (“_id”), unless you put it in the document.

Query data

db.<collection>.find()[.pretty()]  # all the values of all the documents within the collection
db.<collection>.findOne()  # first document in the collection

db.<collection>.find(
    {"studentNo" : "2"}  # where condition (equal)
)
db.<collection>.find(
    {"age" : {$gt : "15"}}  # where condition (gt, gte, lt, lte, ne)
)

db.<collection>.find(
    {"firstName" : "Mark", "age" : "10"}}  # where condition (and of conditions -- with comma)
)
db.<collection>.find(
    {$or : [{"firstName" : "Mark"}, {"age" : "15"}]}  # where condition (or of conditions)
)
db.<collection>.find(
    {"firstName" : "Mark", $or : [{"age" : "16"}, {"age" : "15"}]}}  # where condition (mixed conditions)
)

Update documents (or multiple documents)

General instruction:

db.<collection>.update(
    {<conditions>},  # how to filter documents
    {<values>}  # which values to update
)

Examples:

db.<collection>.update(
    {"_id" : ObjectId("123456")},
    {$set : {"LastName" : "Masen"}}
)

db.<collection>.update(
    {"age" : "16"},    # only the 1st document matching the condition!!
    {$set : {"LastName" : "Wogh"}}
)

db.<collection>.update(
    {"age" : "16"},    
    {$set : {"LastName" : "Wogh"}},
    {multi : true}    # all the (multiple) documents matching the condition!!
)

A particular way of inserting / updating documents:

db.<collection>.save(
    {
        "name":"carl",
        "surname":"browns",
        "age":"10"
    }
)

If not present, adds it (insert). If present, set the current values (update).

Match is done by “_id”.

Delete / Remove document

db.<collection>.remove()  # remove all the documents in the collection
db.<collection>.remove(   # remove documents matching the conditions
    {
        # conditions here
    }
)

Examples:

db.<collection>.remove(   # remove single document (match is done with unique identifier)
    {
        "_id" : ObjectId("2345555")
    }
)

db.<collection>.remove(   # remove multiple documents (all matching conditions)
    {
        "age" : "16"
    }
)

db.<collection>.remove(   # remove N document (the first N matching conditions)
    {
        "age" : "16"
    }, 1  # <-- in this case, N=1 and only the first document with age=16 is deleted
)

Projections

To select only necessary fields rather than all the fields of a document.

db.<collection>.find({},{KEY:1})  # 1: true, 0: false -> do you want to see the KEY field?

Examples:

db.<collection>.find({},{"LastName":1})  # only _id and LastName (if not specified, _id is always shown)
db.<collection>.find({},{"LastName":1, "_id":0})  # only LastName

Limit, sort, skip

Limit: to only select the top N records

db.<collection>.find({},{"StudentNo":1, "FirstName":1, "_id": 0}).limit(4)

The top-4 students, displayed as (Number, FirstName)

Skip: to skip the first N records

db.<collection>.find({},{"StudentNo":1, "FirstName":1, "_id": 0}).skip(2)  

All the students but the first 2, displayed as (Number, FirstName)

Sort: to order records according to the given fields

db.<collection>.find({},{"StudentNo":1, "FirstName":1, "_id": 0}).sort({"FirstName": 1})  

1 = ascending order; -1 = descending order

Mixed example:

db.<collection>.find({},{"StudentNo":1, "FirstName":1, "_id": 0})
    .sort({"FirstName": -1})
    .skip(2)
    .limit(3)

Order all the students by descending first name, and take the 3rd, 4th and 5th ones.

Indexing

Indexed access to efficiently access sparse and large databases.

To add an index on field “myfield”

db.<collection>.ensureIndex({"myfield" : 1})

To remove an index on field “myfield”

db.<collection>.dropIndex({"myfield" : 1})

Example:

# insert 1000000 documents
for(i=0; i < 1000000; ++i) {
    db.<collection>.insert({"student_id": i, "Name": "Mark"});
}

# retrieve single(multiple) element(s)
db.<collection>.findOne({"student_id": 1000})  #immediate! (just one, the first matching)
db.<collection>.find({"student_id": 1000})  #slow! (many documents might match, check them all)

# add an index on student_id
db.<collection>.ensureIndex({"student_id" : 1})

# rerun the query
db.<collection>.findOne({"student_id": 1000})  #immediate! (as before)
db.<collection>.find({"student_id": 1000})  #immediate! (now it is indexed)

Note: do not add an index for every field, but just for unique ones!

Aggregation

Groups values from different documents and perform a variety of operations on the grouped data.

Return a single value after the aggregation (e.g. select count(*) from … group by … -> in this case the aggregated value is the count).

db.<collection>.aggregate(  # group by gender, aggregation op = count.
    [
        {$group : {_id : "$Gender", GenderCount : {$sum : 1}}}  # others are sum, min, max, avg, count, ...
    ]
)

db.<collection>.aggregate(  # group by gender, aggregation op = max.
    [
        {$group : {_id : "$Gender", MaxAge : {$max : "$Age"}}}  # others are sum, min, max, avg, count, ...
    ]
)

db.<collection>.aggregate(  # group by gender, aggregation op = min.
    [
        {$group : {_id : "$Gender", MinAge : {$min : "$Age"}}}  # others are sum, min, max, avg, count, ...
    ]
)

Backup and Restore

mongodump  # backup command
mongorestore  # restore command

# Files are backed up and restored from <mongodir>/bin/<dump_folder> folder
<mongodir>
| - ...
| - bin
|    |- ...
|    |- dump
|    |   |- database_1
|    |   |   |- collection_1.bson
|    |   |   |- collection_2.bson
|    |   |- database_2
|    |   |   |- collection_1.bson

For whole databases

mongodump  # backup all the databases     
mongodump --db <database_name>  # for selective backup

mongorestore  # restore all the databases
mongorestore --db <database_name> /path/to/<database_name>  # for selective restore

For specific collections of a database

mongodump --db <database_name> --collection <collection_name>
mongorestore --db <database_name> --collection <collection_name> /path/to/<collection_name>.bson