WEBVTT 0 00:00.540 --> 00:00.840 All right. 1 00:00.840 --> 00:08.040 So in the last lesson we looked at one way of getting our Node.js app to work with the MongoDB database. 2 00:08.220 --> 00:13.330 And that was through the use of the native MongoDB driver. 3 00:13.770 --> 00:19.020 You saw just how painful it was to do something very simple. 4 00:19.050 --> 00:25.740 I mean in the Mongo shell it was like three or four lines of commands and it turned into 20, 30 lines 5 00:25.740 --> 00:28.460 of code through using the native driver. 6 00:28.650 --> 00:34.590 And a lot of that was down to adding in validation code and writing a lot of the boilerplate or just 7 00:34.590 --> 00:37.930 the simple act of connecting to the MongoDB server. 8 00:38.370 --> 00:45.450 This is why most Node developers who are working with MonoDB who use a package called Mongoose and 9 00:45.510 --> 00:49.640 this is what's called an ODM or an Object Document 10 00:49.640 --> 00:56.310 Mapper. What it will do is it will allow your Node.js app which speaks the language of Javascript objects 11 00:56.580 --> 01:03.120 to be able to talk to your MongoDB database which speaks in the language of documents and collections 12 01:03.240 --> 01:04.840 and databases. 13 01:05.040 --> 01:09.780 And the main objective of this framework is to simplify the writing of validation code, 14 01:09.960 --> 01:12.500 the writing of your business logic boilerplate 15 01:12.600 --> 01:18.780 and just to make the code just shorter and easier to work with. And essentially everything that we did 16 01:18.780 --> 01:25.470 previously using the MongoDB driver, if we were to use Mongoose, all we have to write is pretty much 17 01:25.470 --> 01:27.060 just this right? 18 01:27.060 --> 01:32.510 We require the mongoose package, we connect to the database and we create a new database 19 01:32.520 --> 01:39.260 if it doesn't exist. And then we create a new model of how our data will be represented. 20 01:39.300 --> 01:40.600 This is the only new part 21 01:40.620 --> 01:46.360 and we're going to be going through it in detail. And then with that new model we will create a new document. 22 01:47.340 --> 01:51.930 And then we simply just save our model into the MongoDB database. 23 01:51.990 --> 01:53.830 So it's vastly shorter 24 01:53.880 --> 01:57.900 and I'm going to talk through it in detail and show you how we can use it. 25 01:58.860 --> 02:02.760 Way way back when we were working with the document object model, 26 02:02.910 --> 02:07.790 if you remember it was quite a pain to write all of the code for the DOM. 27 02:07.920 --> 02:13.500 But then when we started using JQuery and we started adding those dollar signs everywhere, everything 28 02:13.500 --> 02:17.510 got a lot shorter and a lot simpler and easier to work with. 29 02:17.670 --> 02:20.660 Well essentially Mongoose does the same job. 30 02:20.820 --> 02:27.240 So let's go ahead and see how we can use Mongoose to make our fruits database way way simpler. 31 02:28.040 --> 02:32.780 First things first, make sure that you've got a active MongoDB server that's running. 32 02:33.260 --> 02:40.090 And then if you open up a Mongo shell and you say, "show dbs", you can see that we've got our fruits 33 02:40.090 --> 02:47.290 DB already created and you can see that it's so small that it doesn't even really register a size. 34 02:47.530 --> 02:51.350 But this time we're going to create our fruitsDB and all of the data inside 35 02:51.370 --> 02:53.440 using just Mongoose. 36 02:53.440 --> 02:56.240 So I'm going to actually delete that database. 37 02:56.240 --> 03:01.960 And in the Mongo shell in order to delete an entire database, what you have to do is you first have to 38 03:01.960 --> 03:03.460 switch to that database. 39 03:03.490 --> 03:05.930 So you'll say use fruitsDB 40 03:06.920 --> 03:09.400 and we've switched to this particular database. 41 03:09.460 --> 03:17.280 And then we just say "db.dropDatabase" and then a set of parentheses to run that command 42 03:17.440 --> 03:20.330 and now we no longer have the fruitsDB. 43 03:20.350 --> 03:26.220 So if I say, "show dbs", you can see that it's been wiped from MongoDB server. 44 03:27.490 --> 03:35.080 Now we're ready to head back into our app.js and we're going to modify all of this code and instead 45 03:35.110 --> 03:39.760 of using the native MongoDB driver, we're going to use Mongoose. 46 03:39.820 --> 03:45.430 And I'm just going to show you just how much it cuts down on our code and how much simpler and easier 47 03:45.430 --> 03:48.310 to understand the code becomes. 48 03:48.430 --> 03:51.720 First things first, we have to require Mongoose. 49 03:51.880 --> 03:57.310 So I'm going to delete these two lines where we're requiring the native Mongo client and the assert 50 03:57.310 --> 03:59.790 testing package. In our app. 51 03:59.790 --> 04:03.180 js, we now want to use this package called Mongoose. 52 04:03.310 --> 04:07.640 But if you remember we haven't actually installed it using NPM yet. 53 04:07.840 --> 04:15.130 So if you head over to hyper and make sure that you are still inside your fruits project, then go ahead 54 04:15.160 --> 04:19.930 and use npm install to install the mongoose package. 55 04:23.580 --> 04:30.840 Once that's done then we can go ahead and move on to the next goal which is to connect to our Mongo 56 04:30.840 --> 04:32.410 DB database. 57 04:32.430 --> 04:38.310 Now you can see at the moment in order to do that we're taking up something like 20 lines of code and 58 04:38.310 --> 04:44.160 some of that will be validation code and some of it will just be the simple act of connecting to the 59 04:44.160 --> 04:45.240 database. 60 04:45.240 --> 04:50.690 Now I want to show you just how simple all of that becomes by using Mongoose instead. 61 04:50.820 --> 04:57.000 So we'll write mongoose.connect and then we're going to open up a set of parentheses 62 04:57.270 --> 05:04.080 and we're going to add the URL that we want to connect to. That connection URL will look very 63 05:04.080 --> 05:05.960 similar to what we've got here. 64 05:06.210 --> 05:18.260 It's going to be a string that is mongodb://localhost:27017. 65 05:18.260 --> 05:25.250 That will specify the port where we can access our MongoDB database server. 66 05:25.460 --> 05:31.460 And then all we have to do is put another forward slash at the end of there and then we can specify 67 05:31.580 --> 05:36.950 the name of the database that we want to create or connect to. 68 05:36.950 --> 05:43.640 So it's going to make a connection to our MongoDB server and then it's going to look for a database 69 05:43.640 --> 05:52.310 called fruitsDB, and if it doesn't exist, then it will create this brand new database. And that replaces 70 05:52.760 --> 05:54.980 all of this. 71 05:55.190 --> 06:01.440 So we can now go ahead and delete all of that. 72 06:01.610 --> 06:12.200 And now if I hit save and we go over to our hyper terminal and use node app.js to run our app, then 73 06:12.260 --> 06:19.210 you can see we've now started our server but we still get the same deprecation warning as we saw before. 74 06:19.220 --> 06:24.340 Now we have to again pass this useNewUrlParser. 75 06:24.770 --> 06:31.840 If we again copy this and paste it into Google to remind ourselves of what that solution was, 76 06:35.370 --> 06:40.470 you can see that this person who's answered is actually very kindly included what you should do if you're 77 06:40.470 --> 06:43.270 using Mongoose to connect to your database. 78 06:43.500 --> 06:45.500 And this is basically what we have to do. 79 06:45.510 --> 06:48.900 We have to add it right at the end of the connect method. 80 06:48.930 --> 06:53.060 So let's go ahead and add that in to change our code. 81 06:53.250 --> 06:58.530 So we've got mongoose.connect and then this is the URL you want to connect to and then we're going to 82 06:58.530 --> 07:05.970 add that new option at the end here which is to use the new url parser and this will resolve that deprecation 83 07:05.970 --> 07:08.170 warning. 84 07:08.180 --> 07:13.110 So now the next thing that we want to do is to insert some data. 85 07:13.310 --> 07:19.580 And you can see that we're doing that right now through these 20 lines. But this code is essentially 86 07:19.580 --> 07:23.390 very similar to what we saw when we were using the Mongo shell. 87 07:23.390 --> 07:28.430 Now I want to show you how you would do that with Mongoose because it's a little bit different from 88 07:28.550 --> 07:30.450 what we've done so far. 89 07:30.890 --> 07:36.220 The first thing we have to do is to create a new schema. 90 07:36.500 --> 07:43.480 And this is basically a blueprint or the structure of our data that we're going to save into our Mongo 91 07:43.480 --> 07:50.910 DB database. In order to do this we can create a new const that's called fruitsSchema. 92 07:52.200 --> 07:57.990 And this is going to be equal to a new mongoose schema. 93 08:00.340 --> 08:07.390 And then we open up a set of parentheses and inside that we add a new Javascript object, 94 08:07.420 --> 08:09.970 so we open up our curly braces. 95 08:10.180 --> 08:18.120 Now in this schema, we basically scaffold out how we want data in a particular collection to be structured. 96 08:18.130 --> 08:24.640 So for example if we were creating a new fruit document, what would the structure of that data look 97 08:24.640 --> 08:25.130 like? 98 08:25.330 --> 08:34.000 Well it might have a name which is going to be of data type string, and then it might have maybe a rating 99 08:34.540 --> 08:44.390 which will be a number, and then it might have just a review which will be a text review for that fruit. 100 08:44.480 --> 08:48.820 This is what our fruit schema would look like using Mongoose 101 08:48.830 --> 08:56.110 and this lays out the foundation for every new fruit document that will be added to our database. After 102 08:56.110 --> 08:57.410 we create the schema, 103 08:57.550 --> 09:09.020 we use the schema to create a Mongoose model. And we do that by saying const Fruit = mongoose 104 09:09.440 --> 09:12.650 .model. 105 09:13.100 --> 09:16.540 And then we specify two parameters. 106 09:16.670 --> 09:22.970 The first one is, what is going to be the name of the collection that is going to comply with this particular 107 09:22.970 --> 09:23.750 schema. 108 09:23.990 --> 09:28.090 Well in our case we want to create a collection of fruits right? 109 09:28.220 --> 09:34.220 So we'll have these fruits each as individual records or documents, they'll be saved into a collection 110 09:34.490 --> 09:41.460 called fruits and then that will be inside our database called fruitsDB. 111 09:41.640 --> 09:45.180 So the first parameter is always going to be a string here. 112 09:45.420 --> 09:51.880 Now the Mongoose way of doing things is to specify the singular name of your collection. 113 09:51.900 --> 10:00.510 So if you have a collection of fruits then inside here will be the word "Fruit" in a singular form. And 114 10:00.600 --> 10:09.240 Mongoose will very cleverly convert this string into a pluralize form to create your collection. 115 10:09.240 --> 10:17.070 By doing this you will have created a new collection called fruits and those fruits have to stick to 116 10:17.070 --> 10:21.150 the structure that we've specified in the fruit schema. 117 10:22.210 --> 10:28.870 And now and only now are we ready to create a new fruit document. 118 10:29.100 --> 10:33.390 I'm going to create something called "fruit" with a lowercase f. 119 10:33.420 --> 10:42.270 This is going to be a new Fruit with a capital F and this is to show that I'm creating this document 120 10:42.630 --> 10:50.130 from this model that we specified up here which means that it's going to have to stick to this schema 121 10:50.250 --> 10:51.940 that we laid out here as well. 122 10:53.800 --> 11:00.270 So now this new fruit is going to have a name, let's call it Apple. 123 11:00.420 --> 11:04.720 It's going to be an apple that we're going to save into our database. And then we're going to give it 124 11:04.750 --> 11:05.710 a rating. 125 11:05.860 --> 11:07.780 And I'm going to give a rating out of 10. 126 11:07.780 --> 11:12.640 So I think Apples are decent, let's give it a 7 and then 127 11:12.760 --> 11:16.500 let's give it a review 128 11:17.080 --> 11:23.990 "Pretty solid" as fruit. Can't really hate on apples right? 129 11:24.160 --> 11:31.600 And now that we've constructed our new document, all we have to do is say fruit.save. 130 11:31.830 --> 11:40.590 And this calls the save method in Mongoose to save this fruit document into a fruit collection inside 131 11:40.630 --> 11:51.530 our fruitsDB. And that replaces our insertDocuments method from the Mongo client. 132 11:51.560 --> 11:57.080 So at the moment you can see that we don't have our prompt. And whenever you are in that position the 133 11:57.080 --> 12:00.400 first thing that will save is CONTROL + C. 134 12:00.590 --> 12:07.410 This should exit out of any process that the terminal or hyper is currently performing. 135 12:07.700 --> 12:13.250 And in our case, it was because we still had an active connection to our MongoDB server. 136 12:14.460 --> 12:20.700 Now let's run our app.js again to save that new fruit into our database. 137 12:20.700 --> 12:29.640 And if I switch over to our shell then we can go ahead and say "show dbs" to show that we've now updated 138 12:29.700 --> 12:39.090 our database with a new fruitsDB and let's say use fruitsDB and now let's see what collections 139 12:39.090 --> 12:41.890 we have in this database. 140 12:42.120 --> 12:51.540 So we'll say "show collections". And you can see that automatically Mongo has dropped the capsule on the 141 12:51.540 --> 13:00.410 earth and pluralized this fruit that we specified here into a collection of fruits. 142 13:01.200 --> 13:07.160 And it's pretty clever how it does that. Behind the scenes is actually using Lodash to achieve it. 143 13:07.170 --> 13:13.770 We saw that in an earlier module. But essentially it allows you to specify the singular form and work 144 13:13.770 --> 13:15.060 with the singular form. 145 13:15.240 --> 13:21.390 But behind the scenes it will create that collection of fruits for you to be able to work with. 146 13:21.390 --> 13:30.290 So if we say "db.fruits.find" so we show everything that's inside our fruits collection, 147 13:30.300 --> 13:38.070 then you can see we have a single document that has an id, a name, a rating and a review. 148 13:39.400 --> 13:48.040 Now, remember that every single time you run fruit.save it will save the same fruit into your fruits 149 13:48.040 --> 13:50.070 collection in your fruits database. 150 13:50.260 --> 13:55.720 So if you don't want that to happen, then you can just comment out this method call and you won't end 151 13:55.720 --> 13:58.950 up with a whole bunch of apples in your database. 152 13:59.290 --> 14:02.730 But it's now time for a challenge. 153 14:02.770 --> 14:10.450 I want you to create a new collection and this is going to be a collection of people. You need to create 154 14:10.570 --> 14:18.380 the schema for a new person and they need to have two fields: a name and an age. 155 14:18.700 --> 14:26.710 And then you're going to create a new model from that schema of a person and you're going to create a new 156 14:26.710 --> 14:33.640 person who's called John and he's 37. And then you're going to say that new person to our database and 157 14:33.640 --> 14:39.680 show it using the Mongo shell. Pause the video now and complete this challenge. 158 14:42.440 --> 14:42.740 All right. 159 14:42.740 --> 14:45.290 So right below our fruit.save 160 14:45.320 --> 14:51.760 we're going to use the same setup but we're going to apply it to a collection of people now. 161 14:51.980 --> 14:56.750 So we're still connected to the same fruits database which is exactly what we want, but we're going 162 14:56.750 --> 14:59.970 to create a new person schema. 163 15:00.300 --> 15:07.220 And this is going to be a new Mongoose schema and it's going to specify that every person we create 164 15:07.550 --> 15:09.650 has to have a name. 165 15:10.040 --> 15:12.520 And they also probably should have an age. 166 15:12.980 --> 15:16.000 So the name is going to be of data type string 167 15:16.220 --> 15:23.780 and the age will be data type number. And then we're going to create our model of a person from this 168 15:23.780 --> 15:24.770 schema. 169 15:25.280 --> 15:34.220 So it's going to equal mongoose.model and then the singular form of a person is person. But behind 170 15:34.220 --> 15:41.960 the scenes we will get a collection called people that will be created. And these people inside the collection 171 15:42.260 --> 15:44.810 will follow the person schema. 172 15:46.260 --> 15:54.810 Using that schema we're going to create a new person and this new person is going to have a couple of 173 15:54.810 --> 15:55.720 values. 174 15:55.920 --> 16:07.180 It's going to have a name of John and an age of 37. And now we can take this person that we created and 175 16:07.180 --> 16:10.220 we can save it to our database. 176 16:10.240 --> 16:18.790 So now if we go back to our terminal and we exit our previous database connection and we run on node 177 16:19.080 --> 16:28.470 app.js again, we can go to our Mongo shell and confirm that if we say "show collections" we now have 178 16:28.470 --> 16:31.920 a collection of fruits and a collection of people. 179 16:31.980 --> 16:38.370 And as I said it's pretty clever about converting your singular form into a pluralized collection. 180 16:38.370 --> 16:49.530 Now if we say "db.people.find" then we end up showing all the documents that we have inside our 181 16:49.560 --> 16:52.990 people collection which, is John who's 37. 182 16:53.920 --> 17:01.150 What if we wanted to add a bunch of fruits in bulk like we did previously using the native MongoDB 183 17:01.150 --> 17:01.970 driver? 184 17:02.320 --> 17:08.950 Well let's say that we create some new fruits. Let's say const we create a kiwi. And this is going to 185 17:08.950 --> 17:17.690 be a new Fruit with a capital F and the kiwi is of course called kiwi. 186 17:17.700 --> 17:30.280 It has a score of "10" because kiwis are awesome and has a review of "The best fruit". And then I'm just 187 17:30.280 --> 17:37.510 going to go in and add two more fruits, orange and banana. Oranges too sour for me and bananas have a 188 17:37.510 --> 17:38.760 really weird texture. 189 17:39.010 --> 17:40.670 So those are three fruits. 190 17:40.670 --> 17:50.680 And now in order to save it in bulk, we can tap into our fruit model and we can say "insertMany". 191 17:50.920 --> 17:53.640 Now how did I know that I could use fruit. 192 17:53.680 --> 17:54.760 insertMany? 193 17:55.180 --> 17:57.140 Well the documentation of course. 194 17:57.310 --> 18:04.810 So if you head over to Mongoose and click on "Read the docs" then inside the API section you can see that they've 195 18:04.810 --> 18:09.140 got all of the methods that you can do with the model listed in here. 196 18:09.400 --> 18:14.440 And very often when you're working with a new package you'll be reading through the documentation and 197 18:14.440 --> 18:16.890 digging through it to see what it can do. 198 18:16.900 --> 18:25.000 So here we have this method called Model.insertMany and it allows us to insert an array of documents 199 18:25.360 --> 18:30.810 into a particular model or basically our collection. 200 18:31.000 --> 18:33.370 The syntax basically looks like this. 201 18:33.370 --> 18:39.130 You specify the name of your Mongoose model which will allow it to connect to the relevant collection 202 18:39.460 --> 18:41.560 and also know what the schema is 203 18:41.560 --> 18:43.780 it should work with. 204 18:44.090 --> 18:45.640 And then we use that method 205 18:45.650 --> 18:48.370 insertMany and it takes two parameters. 206 18:48.440 --> 18:53.180 The first one is an array of objects that match that particular schema, 207 18:53.240 --> 18:56.230 so all fruits here. We've got kiwi, orange and bananas. 208 18:56.240 --> 19:06.050 So we'll add that kiwi, orange and banana. And then the second parameter will be a callback and it allows 209 19:06.050 --> 19:14.010 us to log any errors if there were any issues with inserting all of these objects into our fruits collection. 210 19:14.150 --> 19:27.150 And so we can check say if there's an error then we'll log the error, but else then we'll log "Successfully 211 19:27.480 --> 19:40.400 saved all the fruits to fruitsDB". And let's close that off and let's hit save and exit out of our database 212 19:40.490 --> 19:42.820 and run our app.js again. 213 19:42.950 --> 19:48.550 You can see that we've got that callback, "Successfully saved all of the fruits to the fruitsDB". 214 19:48.620 --> 19:49.850 So there were no errors 215 19:49.880 --> 19:57.900 and if we go and check our db.fruits.find, then 216 19:57.920 --> 20:00.950 we now have a few more fruits. 217 20:00.950 --> 20:04.740 We've got apple, kiwi, orange and banana. 218 20:05.600 --> 20:13.700 We've now seen how you can create new documents and new collections using Mongoose and MongoDB. But how 219 20:13.700 --> 20:19.320 exactly do we access these items in our database through our app.js? 220 20:19.370 --> 20:23.640 How do we get access to living objects that our app can tap into? 221 20:23.840 --> 20:26.210 Well that's what we're going to look at in the next lesson.