Showing posts with label MongoDB. Show all posts
Showing posts with label MongoDB. Show all posts

Wednesday, February 3, 2021

MongoDB vs Mongoose

Mongoose is an Object Data Modelling Library(ODM) for MongoDB and Node.js, providing a higher level of abstraction. It is similar to the relationship between Express and Node, as Express is a layer of abstraction over Node.js while Mongoose is a layer of abstraction over the regular MongoDB driver.


And basically, an object data modelling library is simply a way for us to write our JavaScript code that will interact with the database. We use Mongoose over several other MongoDB drivers, because of the out of box functionalities, that allows for faster and simpler development of our applications. Some of the features that Mongoose provides us are schemas to structure and model our data and relationship, easy data validation, simple query APIs and much more.

Installing Mongoose and Connecting it to our Database

1. Create a new project, and use the command npm init to initialize the project. 


  npm init

2. To install Mongoose, use the command npm install mongoose 


  npm install mongoose

 

3. Now, let us connect our MongoDb database to Mongoose

  a) Create a file called app.js and include the following code –


 // Requiring mongoose
 const mongoose = require("mongoose");

 // Connecting to Database
 mongoose.connect("mongodb://localhost:27017/studentDB");

Here, we have first created an instance of mongoose and then saved our MongoDb connection string in the Db object. Make sure that the mongo shell is running, while you do operations on the database.

   b) Connecting to the database -

Include the following code -


mongoose
   .connect("mongodb://localhost:27017/studentDB", {
     useNewUrlParser: true,
     useUnifiedTopology: true,
     useFindAndModify: false,
  })
  .then(() => console.log("Connection Successfull...!!"))
  .catch(() => console.log("Error, Not Connected"));

Here, mongoose.connect() returns a promise, we have used then here to receive the promise, but we can also use async-await here.

 

4. Now, run node app.js to run the app. We get the following output in the console –
 

node app.js

 So, Mongoose is now successfully connected to our database. 

Mongoose Schema vs Model

While Mongo is schema-less, SQL defines a schema via the table definition. A Mongoose ‘schema’ is a document data structure (or shape of the document) that is enforced via the application layer. In Mongoose, a schema is where we model our data, where we describe the structure of the data, the default values, the constraints, and validation.

Now, Mongoose is all about Models and a model is like a blueprint that we use to create, query, update and delete documents. To perform any CRUD operations, we need a Mongoose model, and to create a model, we need a schema.

For instance, let us create a schema for Student. A student will surely have a name, course, and duration.

 
const studentSchema = new mongoose.Schema();

Here, we have created an instance of the mongoose schema, but it isn't completed yet. We need to pass in the object of the required schema to it.


const studentSchema = new mongoose.Schema({
   name: String
   });

 Here, we have specified our first attribute, or the first field for the document, name. Mongoose uses native JavaScript datatypes, so here we can specify any data type - String, Number, Array, Date or Boolean. This is the most basic way of describing our data. Now, let us add more fields for this schema.


const studentSchema = new mongoose.Schema({
   name: 
{
type: String,
required: true
},
   course: String,
   duration: Number,
  reg: Boolean,
   date: {
     type: Date,
     default: Date.now,
  },
});
 

Note how we have made the name as required, but the other fields need not be necessarily there except date as default, if user not enter anything, it will be set as default.

Now, for the required attribute, we can also pass in the error statement that we want to be displayed when we're missing the field. We just need to pass an array to the required field, as follows -

const studentSchema = new mongoose.Schema({
  name: {
    type: String,
    required: [true"Name field Missing"],
}
  }); 

We can also specify default values, for instance, let's save the default value of our date as Date.now which will store the current date and time of student admission.

So, this is our very basic schema, and let's now create a model out of it.


const Student = new mongoose.model("Student", studentSchema);

 

📝 Creating Documents -

We use our Student modal to create a new document, just like we create an object using classes in Javascript.

To create a new student with values :


  name: "pankaj",
  course: "btech",
  duration: 4,
  reg: true,
 

To create this as a document, include the following code -


const stu1 = new Student({
   name: "pankaj",
   course: "btech",
   duration: 4,
  reg: true,
});
 

This creates a new document and stores it to stu1. To save the document, we use the save() method. 


stu1.save()
   .then((doc) => console.log(doc))
   .catch((error) => console.log(err));

save() method also returns a promise when we save the document.

Now, run the app - node app.js, we get the following output in the console.

 

You may verify that the document is saved, by running db.students.find() in the mongo shell, to see all the documents in the database.


📝 Creating Multiple Documents - 

Now, let us try to save multiple documents to the collection -


const stu2 = new Student({
   name: "manish",
   course: "mba",
  duration: 4,
   reg: true,
});

const stu3 = new Student({
   name: "sachin",
   course: "mca",
  duration: 2,
   reg: true,
});

const stu4 = new Student({
   name: "sneha",
   course: "bca",
  duration: 3,
   reg: true,
});

Student.insertMany([stu2, stu3, stu4])
   .then((doc) => console.log(doc))
   .catch((err) => console.log(err));


Now, let us try to save a document in which name of the student is missing as name is required field –

Now, if we try to run node app.js, we get the following error -

Now, correct your data and run the command Student.insertMany() to insert multiple records in the collection. app, and we get the following output on the terminal -

 And also from the mongo shell, we can verify that our document has been saved -

📝 Reading documents -

We have the find() method to read documents from a collection. To read documents, we use all of the methods directly on the model object.

For instance, to read all documents from the Student model, include the following code:


  const docs = Student.find()
   .then((doc) => console.log(doc))
   .catch((error) => console.log(err));

This gives the following output -

To search for a particular document, we may specify the required attributes and values and pass it as an object to the find() method.

For instance, if we want to find the student with course btech', the following code would work -


const docs = Student.find({ name: "manish" })
   .then((doc) => console.log(doc))
   .catch((error) => console.log(err));

 This gives the following output -

📝 Updating documents -

To update a document, we need its _id which in our case is automatically created by MongoDB.

To update a document, we use the method findByIdAndUpdate() on the model object. The method takes in the _id as a parameter.

For instance - to update the duration of MCA, include the following code in the program -


const docs = Student.findByIdAndUpdate("601acc5f7275a622ec3b3a03", {
   duration: 2,
})
   .then((doc) => console.log(doc))
   .catch((err) => console.log(err));
 

Here, "5d794e71922481309c8e6883" is the id of the document. We can verify if the document has been updated using db.students.find() in the mongo shell.

We get the following output -

The duration for course of MCA has been successfully updated.

📝 Deleting Documents -

Deleting a document through Mongoose is very easy. We use the method findByIdAndDelete and pass the id of the document to be deleted as the parameter -

For instance, if we want to delete our first document, include the following code -


const docs = Student.findByIdAndDelete("601acc5f7275a622ec3b3a05")

This deletes the document with _id="5d794e71922481309c8e6883". We may verify the delete operation through our mongo shell.

We get the following results-

The document has been successfully deleted.

And we are all done ! 🎉

             

Monday, February 1, 2021

MongoDB Indexes

 

Student Collection: Download Student.json

> show dbs
CRUD     0.000GB
admin    0.000GB
config   0.000GB
local    0.000GB
> use CRUD
switched to db CRUD
> show collections
skill
student
test
> db.student.getIndexes()
[
        {
                "v" : 2,
                "key" : {
                        "_id" : 1
                },
                "name" : "_id_",
                "ns" : "CRUD.student"
        }
]
> db.student.createIndex({id:1},{unique:true})
{
        "createdCollectionAutomatically" : false,
        "numIndexesBefore" : 1,
        "numIndexesAfter" : 2,
        "ok" : 1
}
> db.student.createIndex({sec:1},{unique:true})
{
        "ok" : 0,
        "errmsg" : "E11000 duplicate key error collection: CRUD.student index: sec_1 dup key: 
        { sec: \"A\" }",
        "code" : 11000,
        "codeName" : "DuplicateKey",
        "keyPattern" : {
                "sec" : 1
        },
        "keyValue" : {
                "sec" : "A"
        }
}
> db.student.getIndexes()
[
        {
                "v" : 2,
                "key" : {
                        "_id" : 1
                },
                "name" : "_id_",
                "ns" : "CRUD.student"
        },
        {
                "v" : 2,
                "unique" : true,
                "key" : {
                        "id" : 1
                },
                "name" : "id_1",
                "ns" : "CRUD.student"
        }
]
> db.student.find({"id":3})
"_id" : ObjectId("601193736aed415ccc1d4bc1")"name" : "kamal""lastName" : "sharma""age" : 11
    "averageScore" : 6.4"id" : 3"sec" : "A""gender" : "male" }
>
> db.student.explain().find({id:3})
{
        "queryPlanner" : {
                "plannerVersion" : 1,
                "namespace" : "CRUD.student",
                "indexFilterSet" : false,
                "parsedQuery" : {
                        "id" : {
                                "$eq" : 3
                        }
                },
                "queryHash" : "6DAB46EC",
                "planCacheKey" : "801B9D84",
                "winningPlan" : {
                        "stage" : "FETCH",
                        "inputStage" : {
                                "stage" : "IXSCAN",
                                "keyPattern" : {
                                        "id" : 1
                                },
                                "indexName" : "id_1",
                                "isMultiKey" : false,
                                "multiKeyPaths" : {
                                        "id" : [ ]
                                },
                                "isUnique" : true,
                                "isSparse" : false,
                                "isPartial" : false,
                                "indexVersion" : 2,
                                "direction" : "forward",
                                "indexBounds" : {
                                        "id" : [
                                                "[3.0, 3.0]"
                                        ]
                                }
                        }
                },
                "rejectedPlans" : [ ]
        },
        "serverInfo" : {
                "host" : "LAPTOP-7HHTVTQF",
                "port" : 27017,
                "version" : "4.2.2",
                "gitVersion" : "a0bbbff6ada159e19298d37946ac8dc4b497eadf"
        },
        "ok" : 1
}
> db.student.explain().find({age:25})
{
        "queryPlanner" : {
                "plannerVersion" : 1,
                "namespace" : "CRUD.student",
                "indexFilterSet" : false,
                "parsedQuery" : {
                        "age" : {
                                "$eq" : 25
                        }
                },
                "queryHash" : "3838C5F3",
                "planCacheKey" : "3838C5F3",
                "winningPlan" : {
                        "stage" : "COLLSCAN",
                        "filter" : {
                                "age" : {
                                        "$eq" : 25
                                }
                        },
                        "direction" : "forward"
                },
                "rejectedPlans" : [ ]
        },
        "serverInfo" : {
                "host" : "LAPTOP-7HHTVTQF",
                "port" : 27017,
                "version" : "4.2.2",
                "gitVersion" : "a0bbbff6ada159e19298d37946ac8dc4b497eadf"
        },
        "ok" : 1
}
> db.student.createIndex({age:1},{name:"myAgeIndex"})
{
        "createdCollectionAutomatically" : false,
        "numIndexesBefore" : 2,
        "numIndexesAfter" : 3,
        "ok" : 1
}
> db.student.getIndexes()
[
        {
                "v" : 2,
                "key" : {
                        "_id" : 1
                },
                "name" : "_id_",
                "ns" : "CRUD.student"
        },
        {
                "v" : 2,
                "unique" : true,
                "key" : {
                        "id" : 1
                },
                "name" : "id_1",
                "ns" : "CRUD.student"
        },
        {
                "v" : 2,
                "key" : {
                        "age" : 1
                },
                "name" : "myAgeIndex",
                "ns" : "CRUD.student"
        }
]
> db.student.insert({id:20"name":"pankaj"})
WriteResult({
        "nInserted" : 0,
        "writeError" : {
                "code" : 11000,
                "errmsg" : "E11000 duplicate key error collection: CRUD.student index: id_1 dup key: 
                { id: 20.0 }"
        }
})
> db.student.insert({id:21, "name":"pankaj"})
WriteResult({ "nInserted" : 1 })
> db.student.insert({id:22, "name":"pankaj"age:31})
WriteResult({ "nInserted" : 1 })

> db.student.dropIndex({age:1})
"nIndexesWas" : 3"ok" : 1 }

> db.student.getIndexes()
[
        {
                "v" : 2,
                "key" : {
                        "_id" : 1
                },
                "name" : "_id_",
                "ns" : "CRUD.student"
        },
        {
                "v" : 2,
                "unique" : true,
                "key" : {
                        "id" : 1
                },
                "name" : "id_1",
                "ns" : "CRUD.student"
        }
]
> db.student.dropIndexes()
{
        "nIndexesWas" : 2,
        "msg" : "non-_id indexes dropped for collection",
        "ok" : 1
}