Mongo DBPlus
Mongo DBPlus
MongoDB Definition
MongoDB is an object-oriented, simple, dynamic and
scalable NoSQL database. It is based on the NoSQL document storage
model where the data objects are stored as separate and flexible JSON-
like documents. The data objects are stored in a collection instead of
columns and rows like a traditional relational database. This means that
the fields can differ from one document to another and data structure can
be changed over time.
The goal and purpose of MongoDB is to offer a data store that has high-
performance, high-availability and horizontal scaling. MongoDB is easy to
install and free to use.
Versions released prior to October 16, 2018, are published under the AGPL
and its general distributions support Windows, Linux, Mac OS X, and
Solaris.
Why is using MongoDB better than
using MySQL? 🤔
Organizations of all sizes are choosing MongoDB because it helps them
build applications faster and handle multiple different types of data. It also
assists them in managing applications more efficiently depending on the
size of the project.
Assessment: Quiz
MongoDB is generally used at the _________________.
Install MongoDB
Installation ⚙️
MongoDB is available in two server editions: Community and Enterprise.
MongoDB Enterprise provides various features that not available in the
MongoDB Community edition, such as In-Memory Storage Engine,
Auditing, Kerberos Authentication…
Windows ½
Windows installation
To install MongoDB on windows OS, you only have to visit the link and
follow the instructions. For Windows 7 and older, you should remove the
check button on the mongo compass and install it separately)
Linux Installation:
See at this YouTube link : https://www.youtube.com/watch?v=d4jPEfky3L8
Assessment: Quiz
To install MongoDB, we need a special operating system.
True False
To verify MongoDB's version, we use the command:
True False
Database Management
Database Management 🕹️
db.getName()
Returns: the current database name.
db.version()
Returns: The mongod version or mongos instance.
db.stats(scale)
The db.stats() method returns a document with statistics reflecting the
database system’s state.
The scale is used on various data sizes. The scale defaults to 1 in order to
return data sizes in bytes. To display sizes in kilobytes instead of bytes,
specify a scale value of 1024.
Database Management 🕹️
Here is some other database methods:
Database Management 🕹️
db.serverStatus(): Returns a document that provides an overview
of the database process’ state.
Assessment: Quiz
Which of these can provide an insight on MongoDB database process’s state?
Collection Management
Collection Management 🕹️
Now after we have learned how to manipulate a database, it’s
time to manipulate the collections of our database:
P.S. The methods listed on this table of contents page refer to the mongo
shell methods, and not to the MongoDB Node.js driver (or any other
driver) methods.
Collection Management 🕹️
db.collection.stats(): Reports a collection's state.
db.collection.storageSize(): Reports the total storage size used
by the collection in bytes.
db.collection.validate(<option>): Validates a collection. The
method scans a collection data and indexes for correctness and
returns the result.
o full: Optional. A flag that determines whether the command
performs a slower but more thorough check, or a faster but
less thorough check.
db.collection.validate( {
} )
db.collection.validate( <boolean> ) // full option
Collection Management 🕹️
db.collection.explain(verbosity)
Returns information on the query plan for the following methods:
aggregate()
count()
find()
remove()
update()
distinct()
findAndModify()
Verbosity: Optional. Specifies the verbosity mode for the explain output.
The mode affects the behavior of explain() and determines the amount of
information to return. The possible modes are:
"queryPlanner" (Default)
"executionStats"
"allPlansExecution"
db.products.explain("allPlansExecution").update( { $set: { reorder: true
} })
Assessment: Quiz
Which one is not a verbosity mode in the explain method?
The four first letters of each word makes up the CRUD acronym.
Create Document
Create Document 📄
MongoDB provides the following methods to insert documents into a
collection:
db.collection.insert()
db.collection.insertOne()
db.collection.insertMany()
db.collection.save()
Look at this YouTube link : https://www.youtube.com/watch?
v=Br0K85I7DXw
Insert Document 📄
db.collection.insertOne()
<document>,
writeConcern: <document>
Insert Document 📄
db.collection.save()
It updates an existing document or inserts a new document depending on
the parameter.
The save() method uses either the insert or the update command, which
uses the default write concern. To specify a different write concern,
include the write concern in the options parameter.
db.collection.save(
<document>,
writeConcern: <document>
)
db.products.save( { item: "book", qty: 40 } )
Assessment: Quiz
db.collection.save() is still a valid method for mongodb.
True False
MongoDB provides the following methods to insert documents into a collection:
db.collection.insert() db.collection.insertOne() db.collection.insertMany()
True False
Which one of the following operations adds a new document to the users' collection?
Query Documents
Query Documents 🔍
Look at this Youtube link: https://www.youtube.com/watch?
v=Gv5GxcKKRSE
Assessment: Quiz
Which one of the following methods is used to query documents in collections?
Queries specify criteria, or conditions, that identify the documents that MongoDB
returns to the clients Write operations, or queries, retrieve data stored in the
database. The selection limits the amount of data that MongoDB returns to the
client over the network All of the above.
What will be the output?
Update Document
Update Document 📄
db.collection.save()
Updates an existing document or inserts a new document depending on
the document's parameter.
The save() method uses either the insert or the update command, which
uses the default write concern. To specify a different write concern,
include the write concern in the options parameter.
db.collection.save(
<document>,
writeConcern: <document>
Update Document 📄
Look at this YouTube link: https://www.youtube.com/watch?
v=iIugpCh54BA
Assessment: Quiz
What does the following query do when performed on the posts collection?
1
db.posts.update({ _id: 1 }, { $set: { Author: "Tom" } })
Sets the complete document with _id as 1 with the document specified in second parameter
by replacing it completely Adds a new field Author in the searched collection if not already
present Updates only the Author field of the document with _id as 1
True False
Delete Documents 🗑️
Look at this Youtube Link:
https://www.youtube.com/watch?v=NtvtFtEcCQQ
Assessment: Quiz
Which one of the following operations removes a document from MongoDB
collection?
deleteOne() findOneAndDelete()
Which one of the following commands removes a single document that matches the
condition of the author’s name being John?
Mongoose
Mongoose Introduction
What's mongoose?
Mongoose is an Object Data Modeling (ODM) library for MongoDB and
Node.JS. It is responsible for:
The example below is a reminder of how data is stored in Mongo vs. SQL
Database:
Fill in the blanks Solution
Mongoose is a MongoDB object modeling tool or ODM (Object Document Mapper). It's
written in JavaScript and designed to work in an asynchronous environment.
Terminologies
Just as a reminder, here are some terminologies used with the NoSQL
database:
Getting Started
Getting Started
1. Mongo Installation: First, we need MongoDB to be installed in our
machine (check the MongoDB Super Skill if needed)
Fire up your favorite IDE (ahem..VSCode), create a blank project, and let’s
get started! We will be using the limited ES6 syntax in Node, (so we won’t
be configuring Babel).
2. Mongoose Installation
Let’s go to the project folder and initialize our project:
npm init -y
3. Database Connection
Create a file ./src/database.js under the project's root.
Next, we will add a simple class with a method that connects to the
database.
Your connection string will vary based on your installation.
class Database {
constructor() {
this._connect()
_connect() {
mongoose.connect(`mongodb://${server}/${database}`)
.then(() => {
})
.catch(err => {
})
Side Note
About Module import/require work-flow:
In the previous code, we have also turned our database class into a singleton by
returning an instance of the class in the module.exports statement because we
only need a single connection to the database.
ES6 makes it very easy for us to create a singleton (single instance) pattern
because of how the module loader works by caching the response of a previously
imported file.
Solution
Reorder the following function:
function connect() {
mongoose.connect(`mongodb://${server}/${database}`)
.then(() => {
.catch(err => {
}}
1. Referencing Mongoose
let mongoose = require('mongoose')
This reference will be the same as the one that was returned when we
connected to the database, which means the schema and model
definitions will not need to explicitly connect to the database.
email: String
})
Here we define a property called email with a schema type String which
maps to an internal validator that will be triggered when the model is
saved to the database. It will fail if the data type of the value is not a
string type.
The following Schema Types are permitted:
Array
Boolean
Buffer
Date
Mixed (A generic / flexible data type)
Number
ObjectId
String
3. Exporting a Model
We need to call the model constructor on the Mongoose instance and pass
it the name of the collection and a reference to the schema definition.
module.exports = mongoose.model('Email', emailSchema)
email: String
})
We can also create an instance of the model we've defined above and
populate it using the following syntax:
let EmailModel = require('./email')
email: 'ada.lovelace@gmail.com'
})
Let’s enhance the email schema to make the email property a unique and
required field. We can then convert the value to lowercase before saving
it. We can also add a validation function that will ensure that the value is a
valid email address. We will reference and use the validator library
installed earlier.
let mongoose = require('mongoose')
email: {
type: String,
required: true,
unique: true,
lowercase: true,
return validator.isEmail(value)
}
})
Assessment: Quiz
What are the permitted Schema Types in Mongoose?
True False
A schema defines document properties.
True False
Basic Operations
Mongoose has a flexible API and provides many ways to accomplish a task.
We will not focus on the variations because that is out of the scope of this
course. However, try to remember that most of the operations can be
done in more than one way either syntactically or via the application's
architecture.
Create Record
Let’s create an instance of the email model and save it to the database:
let EmailModel = require('./email')
email: 'ADA.LOVELACE@GMAIL.COM'
})
msg.save()
.then(doc => {
console.log(doc)
})
.catch(err => {
console.error(err)
})
_id: 5a78fe3e2f44ba8f85a2409a,
email: 'ada.lovelace@gmail.com',
__v: 0
The following fields are returned (internal fields are prefixed with an
underscore):
If you try to repeat the save operation above, you will get an error
because we have specified that the email field should be unique.
311790:0
Fetch Record
Let’s try to retrieve the record we saved to the database earlier. The
model class exposes several static and instance methods to perform
operations on the database. We will now try to find the record that we
have created previously using the find method and pass the email as the
search term.
EmailModel
.find({
})
.then(doc => {
console.log(doc)
})
.catch(err => {
console.error(err)
})
_id: 5a78fe3e2f44ba8f85a2409a,
email: 'ada.lovelace@gmail.com',
__v: 0
Update Record
Let’s modify the record above by changing the email address and adding
another field to it, all in a single operation. For performance reasons,
Mongoose won’t return the updated document so we need to pass an
additional parameter to ask for it:
EmailModel
.findOneAndUpdate(
},
},
})
.then(doc => {
console.log(doc)
})
.catch(err => {
console.error(err)
})
_id: 5a78fe3e2f44ba8f85a2409a,
email: 'theoutlander@live.com',
__v: 0
Delete Record
We will use the findOneAndRemove call to delete a record. It returns the
original document that was removed:
EmailModel
.findOneAndRemove({
email: 'theoutlander@live.com'
})
.then(response => {
console.log(response)
})
.catch(err => {
console.error(err)
})
Helpers.
Helpers
So far, we have looked at some of the basic functionalities known as CRUD
(Create, Read, Update, Delete) operations, but Mongoose also provides the
ability to configure several types of helper methods and properties. These
can be used to further simplify working with data.
Let’s create a user schema in ./src/models/user.js with the
fields firstName and lastName:
let mongoose = require('mongoose')
firstName: String,
lastName: String
})
Virtual Property
A virtual property is not restricted the database. We can add it to our
schema as a helper to get and set values.
Let’s create a virtual property called fullName which can be used to set
values on firstName and lastName and retrieve them as a combined value
when read:
userSchema.virtual('fullName').get(function() {
})
userSchema.virtual('fullName').set(function(name) {
this.firstName = str[0]
this.lastName = str[1]
})
Callbacks for get and set must use the function keyword as we need to
access the model via the this keyword. Using fat arrow functions will
change what this refers to.
console.log()
console.log(model.fullName) // Output the full name
firstName: 'Thomas',
lastName: 'Anderson' }
Thomas Anderson
Instance Methods
We can create custom helper methods on the schema and access them
via the model instance. These methods will have access to the model
object and they can be used quite creatively. For instance, we could create
a method to find all the people who have the same first name as the
current instance.
In this example, let’s create a function to return the initials for the current
user. Let’s add a custom helper method called getInitials to the schema:
userSchema.methods.getInitials = function() {
firstName: 'Thomas',
lastName: 'Anderson'
})
Static Methods
Similar to instance methods, we can create static methods on the schema.
Let’s create a method to retrieve all users in the database:
userSchema.statics.getUsers = function() {
if(err) {
console.error(err)
return reject(err)
resolve(docs)
})
})
Calling getUsers on the Model class will return all the users in the database:
UserModel.getUsers()
.then(docs => {
console.log(docs)
})
.catch(err => {
console.error(err)
})
Middleware
Middleware is a set of functions that run at specific stages of a pipeline.
Mongoose supports middleware for the following operations:
Aggregate
Document
Model
Query
For instance, models have pre and post functions that take two
parameters:
firstName: String,
lastName: String,
createdAt: Date,
updatedAt: Date
})
Let’s add a pre-save hook and set values for createdAt and updatedAt:
userSchema.pre('save', function (next) {
this.updatedAt = now
if (!this.createdAt) {
this.createdAt = now
}
// Call the next function in the pre-save chain
next()
})
msg.save()
.then(doc => {
console.log(doc)
})
.catch(err => {
console.error(err)
})
You should see values for createdAt and updatedAt when the created record
is printed:
{ _id: 5a7bbbeebc3b49cb919da675,
firstName: 'Thomas',
lastName: 'Anderson',
updatedAt: 2018-02-08T02:54:38.888Z,
createdAt: 2018-02-08T02:54:38.888Z,
__v: 0 }
Plugins
Suppose that we want to track when a record was created and last
updated on every collection in our database. Instead of repeating the
above process, we can create a plugin and apply it to every schema.
schema.add({
createdAt: Date,
updatedAt: Date
})
this.updatedAt = now
if (!this.createdAt) {
this.createdAt = now
next()
})
To use this plugin, we simply pass it to the schemas that should be given
this functionality:
let timestampPlugin = require('./plugins/timestamp')
emailSchema.plugin(timestampPlugin)
userSchema.plugin(timestampPlugin)
Assessment: Quiz
Helpers are functions provided by Mongoose.
True False
Virtual properties are only restricted to the database.
true false
In which operations does Mongoose support middleware?
Query Building
Query Building
Mongoose has a very rich API that handles many complex operations
supported by MongoDB. Let's take for example a query where we can
incrementally build query components.
.then(docs => {
console.log(docs)
})
.catch(err => {
console.error(err)
})
Conclusion
Mongoose RECAP
We have covered the basics Mongoose and what it can do. It is a rich
library full of useful and powerful features that make it a joy to work with
data models in the application layer.
While you can interact with Mongo directly using Mongo Driver, Mongoose
will simplify that interaction by allowing you to model relationships
between data and validate them easily.
Fun Fact: Valeri Karpov the creator of mongoose was the one who coined
the term The MEAN Stack.
REST API
REST API Introduction
Introduction
What is a REST API ?
Let’s say you’re trying to find Batman videos on Youtube. You open up
Youtube, type “Batman” into the search field, hit enter, and you see a list
of videos about Batman. A REST API works in a similar way. You search for
something and you get a list of results back from the service you’re
requesting it from.
True False
RESTful API is only an API that is created under Node.js
True False
Request
The internet boasts a vast array of resources hosted on different servers.
For you to access these resources, your browser needs to be able to send
a request to the servers and display the resources for you. HTTP
(Hypertext Transfer Protocol) is the underlying format that is used to
structure requests and responses for effective client-server
communication. The message that is sent by a client to a server is what is
known as an HTTP request. Clients can use various methods to send
requests to a server.
Therefore, HTTP request methods are the assets that indicate the specific
desired action to be performed on a given resource. Each method
implements a distinct semantic, but there are some standard features that
are shared by the various HTTP request methods.
Assessment: Quiz
The request is sent from the browser to a server.
True False
The request is sent via the SMTP protocol.
True False
The HTTP request can only have one type of method.
True False
Request Headers
Headers are used to provide information to both the client and the server.
It can be used for many purposes, such as authentication and providing
information about the body content.
Assessment: Quiz
Request headers are used to hold messages.
True False
Request headers provide information to servers and clients.
True False
The request header holds only the authentication information.
True False
Request Body
The body (sometimes called “data” or “message”) contains information
you want to be sent to the server. This option is only used with POST, PUT
or DELETE requests.
For a sign in request, a body example can be the email and password.
Assessment: Quiz
The request body can also be called
True False
The request body contains the result of the request.
True False
Response
HTTP Response
When a client (browser) makes a request to a server, the server responds
with a reply including a status code.
HTTP response status codes indicate whether a specific HTTP request has
been successfully completed. Responses are grouped in five classes:
True False
The response is sent from the client to the server.
True False
Assessment: Quiz
The get method is used to send data from the client to the server.
True False
The get method performs a read operation.
True False
The get method is an HTTP method.
True False
Assessment: Quiz
The PUT method is used for the update operation.
True False
The update method contains a body.
True False
The PUT method performs an update on a database entity.
True False
Assessment: Quiz
To delete a document, we send a PUT request.
True False
The delete method is not a HTTP request, it has to be implemented.
True False
After the delete method is performed, the server sends back a success or failure
response.
True False
Conclusion
Recap
We've learned what a REST API is and how to use POSTMAN to perform a
request with GET, POST, PUT, and DELETE methods. Next, we will learn
how to interact with a REST API in a Node JS application.