1
00:00:03,680 --> 00:00:06,035
In the previous lesson,

2
00:00:06,035 --> 00:00:08,550
we learned about the MongoDB driver.

3
00:00:08,550 --> 00:00:14,250
That enables our node application to communicate with a MongoDB server,

4
00:00:14,250 --> 00:00:19,660
and also store and retrieve documents from the MongoDB server.

5
00:00:19,660 --> 00:00:23,310
We also saw that the MongoDB driver provides us with

6
00:00:23,310 --> 00:00:28,770
many methods that enable us to create collections within a database,

7
00:00:28,770 --> 00:00:30,925
add documents to the collections,

8
00:00:30,925 --> 00:00:35,695
and then perform various operations on the documents within a collection.

9
00:00:35,695 --> 00:00:41,060
Now, when the documents are stored in the database,

10
00:00:41,060 --> 00:00:46,330
the MongoDB driver itself imposes no structure on the documents.

11
00:00:46,330 --> 00:00:52,640
If we need to have specific structure for the documents and enforce that structure,

12
00:00:52,640 --> 00:00:58,505
then we need to make use of the Mongoose node module which enables us to define

13
00:00:58,505 --> 00:01:05,015
a schema and a structure for our documents that are stored in our MongoDB database,

14
00:01:05,015 --> 00:01:08,275
and strictly enforces the structure.

15
00:01:08,275 --> 00:01:16,035
Let's look at more details in this lecture and the exercises that follow this lecture.

16
00:01:16,035 --> 00:01:18,540
As we have already learned,

17
00:01:18,540 --> 00:01:25,035
MongoDB stores data in collections in a database.

18
00:01:25,035 --> 00:01:28,695
These collections consists of a collection of documents.

19
00:01:28,695 --> 00:01:30,750
The documents themselves stored in

20
00:01:30,750 --> 00:01:35,405
a MongoDB database have no specific structure imposed on the document.

21
00:01:35,405 --> 00:01:38,570
Any document can be stored in any collection.

22
00:01:38,570 --> 00:01:46,370
MongoDB relies on the developer to enforce the structure on the documents,

23
00:01:46,370 --> 00:01:52,295
and gives the complete responsibility to the developer to make sure that documents

24
00:01:52,295 --> 00:01:58,670
of the correct structure are added and maintained in the various collections.

25
00:01:58,670 --> 00:02:01,960
Now, it is very easy to violate this.

26
00:02:01,960 --> 00:02:06,260
So for example, even though you might start out with the assumption

27
00:02:06,260 --> 00:02:11,030
that a particular connection will have documents of a certain structure,

28
00:02:11,030 --> 00:02:17,045
you can easily insert documents that don't necessarily comply with the structure.

29
00:02:17,045 --> 00:02:21,170
If you are very particular that the structure of the documents in

30
00:02:21,170 --> 00:02:25,550
a collection always have a specified structure,

31
00:02:25,550 --> 00:02:28,550
and always will have the specific set of fields,

32
00:02:28,550 --> 00:02:32,540
then the MongoDB itself doesn't impose that neither

33
00:02:32,540 --> 00:02:36,630
does the node MongoDB driver that we have seen in the previous lesson.

34
00:02:36,630 --> 00:02:40,565
This is where we will need a more formal way of imposing

35
00:02:40,565 --> 00:02:46,385
structure on the documents that are stored in a collection in a MongoDB database.

36
00:02:46,385 --> 00:02:52,390
This is where the Mongoose node module comes to our help.

37
00:02:52,390 --> 00:02:56,405
The Mongoose node module imposes

38
00:02:56,405 --> 00:03:01,875
a standardized structure for the documents that are stored in a particular collection.

39
00:03:01,875 --> 00:03:07,175
So, that is why we often hear people referring to this as the Mongoose ODM.

40
00:03:07,175 --> 00:03:10,950
The ODM itself is interpreted by some people to mean

41
00:03:10,950 --> 00:03:16,995
Object Data Model or sometimes referred to as Object Document Mapping,

42
00:03:16,995 --> 00:03:22,125
or some people refer to it as ORM or Object Relational Mapping.

43
00:03:22,125 --> 00:03:27,755
Now, when we talk about relational that applies a lot more to relational databases,

44
00:03:27,755 --> 00:03:33,380
but then with SQL databases we needed explicitly the object to

45
00:03:33,380 --> 00:03:41,850
relational mapping to be put in between the database and our application itself.

46
00:03:41,850 --> 00:03:45,245
Because within the application we would be looking at

47
00:03:45,245 --> 00:03:50,245
objects but their storage in an SQL database will be in the form of records,

48
00:03:50,245 --> 00:03:52,585
and so you need an explicit mapping.

49
00:03:52,585 --> 00:03:54,870
As we saw with the NoSQL database,

50
00:03:54,870 --> 00:03:56,685
this was not explicitly required.

51
00:03:56,685 --> 00:04:03,710
But if you need to impose structure on your documents that are stored in a collection

52
00:04:03,710 --> 00:04:10,790
then the use of Mongoose to impose this structure is very, very useful.

53
00:04:10,790 --> 00:04:13,880
The way Mongoose goes around

54
00:04:13,880 --> 00:04:18,275
imposing structure on the documents is through the use of schema.

55
00:04:18,275 --> 00:04:21,995
Schema, defines the structure of their documents.

56
00:04:21,995 --> 00:04:24,800
Let's talk about that in a bit more detail.

57
00:04:24,800 --> 00:04:27,580
So, what exactly is mongoose schema,

58
00:04:27,580 --> 00:04:29,700
and what does it bring to the table?

59
00:04:29,700 --> 00:04:34,700
Mongoose schema, implies a structure on

60
00:04:34,700 --> 00:04:39,735
the data that is stored in a document in your database.

61
00:04:39,735 --> 00:04:42,770
So, it defines all the fields of your document,

62
00:04:42,770 --> 00:04:45,349
and also specifies the types of the fields,

63
00:04:45,349 --> 00:04:47,345
and also can provide us with

64
00:04:47,345 --> 00:04:51,965
additional features that can enable validation on these fields.

65
00:04:51,965 --> 00:04:59,425
So, for example, the various schema types that are supported in Mongoose include: String,

66
00:04:59,425 --> 00:05:03,195
Number, Date, Buffer, Boolean,

67
00:05:03,195 --> 00:05:06,295
Mixed, object ID, and Array.

68
00:05:06,295 --> 00:05:09,070
In particular we will look at string number,

69
00:05:09,070 --> 00:05:14,405
and a date, and Boolean in the exercise that follows.

70
00:05:14,405 --> 00:05:18,075
We will look at some of the other ones in later exercises.

71
00:05:18,075 --> 00:05:22,125
In particular, notice the use of the array schema type.

72
00:05:22,125 --> 00:05:25,570
So, an array schema type would allow you to

73
00:05:25,570 --> 00:05:31,640
create an array of sub-documents inside the document.

74
00:05:31,640 --> 00:05:33,740
I'll talk about that in a short while.

75
00:05:33,740 --> 00:05:36,940
Once you define a schema,

76
00:05:36,960 --> 00:05:42,160
the schema is then used in Mongoose to create a model function,

77
00:05:42,160 --> 00:05:49,830
and that is what enables you to define the structure for your documents in the database.

78
00:05:49,830 --> 00:05:53,225
Schemas themselves can have nesting.

79
00:05:53,225 --> 00:05:58,490
So, which means that you can have sub-document that are enclosed inside a document.

80
00:05:58,490 --> 00:06:01,519
The sub-documents typically are accommodated

81
00:06:01,519 --> 00:06:04,890
either through specifying an additional schema,

82
00:06:04,890 --> 00:06:11,870
and then defining one of the fields of the schema to be off the type of the other schema.

83
00:06:11,870 --> 00:06:15,215
Or you can even go with an array of

84
00:06:15,215 --> 00:06:20,000
another schema type within a second schema that you define.

85
00:06:20,000 --> 00:06:24,930
Let's look at an example to clarify some of these in more detail.

86
00:06:24,930 --> 00:06:32,010
This example will be from the exercise that you will do right after this lecture.

87
00:06:32,010 --> 00:06:37,705
Before I can talk about schemas and models in Mongoose,

88
00:06:37,705 --> 00:06:41,310
let's understand why we would need that.

89
00:06:41,310 --> 00:06:43,975
If you have taken the previous angular,

90
00:06:43,975 --> 00:06:46,760
or the ionic, or the native script course,

91
00:06:46,760 --> 00:06:49,445
you have seen that we represent

92
00:06:49,445 --> 00:06:55,565
various data that we use in our applications in the form of JSON strings.

93
00:06:55,565 --> 00:07:02,050
So, in our application we define a collection called as dishes.

94
00:07:02,050 --> 00:07:03,770
In a dish collection,

95
00:07:03,770 --> 00:07:09,700
each dish will contain a certain set of properties defined in the form of JSON string,

96
00:07:09,700 --> 00:07:11,665
as you see in this example here.

97
00:07:11,665 --> 00:07:15,830
So, the dishes is an array of dish type,

98
00:07:15,830 --> 00:07:18,605
and each dish itself will contain a name,

99
00:07:18,605 --> 00:07:20,290
an image, a category,

100
00:07:20,290 --> 00:07:22,015
a label, and so on.

101
00:07:22,015 --> 00:07:26,360
Also, inside the dish document itself,

102
00:07:26,360 --> 00:07:32,830
you would have comments which are stored as an array of again,-

103
00:07:32,830 --> 00:07:38,240
JSON documents which contain specific fields step.

104
00:07:38,240 --> 00:07:39,750
So, each comment, for example,

105
00:07:39,750 --> 00:07:45,685
contains a rating comment author and a date field as you see in this example here.

106
00:07:45,685 --> 00:07:49,215
So, you see that there is a clear structure to

107
00:07:49,215 --> 00:07:55,230
each document that defines a dish that is stored in our database.

108
00:07:55,230 --> 00:08:02,545
Multiple dishes obviously will be stored in the form of a collection in our database,

109
00:08:02,545 --> 00:08:06,655
and could be grouped together and sent over as an array of

110
00:08:06,655 --> 00:08:11,165
dishes to our client application to be made use of.

111
00:08:11,165 --> 00:08:14,890
Now that we have understood how this is defined, now,

112
00:08:14,890 --> 00:08:22,000
how does this relate to the Mongoose schema and the model that we define in Mongoose?

113
00:08:22,000 --> 00:08:27,460
Now, note the structure of a typical dish document here.

114
00:08:27,460 --> 00:08:34,095
So, this could be easily mapped into a MongoDB document in a collection,

115
00:08:34,095 --> 00:08:37,375
perhaps named the dishes collection.

116
00:08:37,375 --> 00:08:42,605
So, we see that there is a clear structure to the document itself.

117
00:08:42,605 --> 00:08:50,320
Now, how do we mirror this in a schema in our Mongoose application?

118
00:08:50,320 --> 00:08:54,095
As you will learn in the exercise,

119
00:08:54,095 --> 00:08:57,900
we will see that we would define schemas in Mongoose.

120
00:08:57,900 --> 00:09:03,085
So the schema is defined as a Mongoose schema here.

121
00:09:03,085 --> 00:09:08,055
As an example, a commentSchema is shown here.

122
00:09:08,055 --> 00:09:09,925
The commentSchema, as you can see,

123
00:09:09,925 --> 00:09:13,885
contains three different fields: the rating, comment,

124
00:09:13,885 --> 00:09:15,445
and the author field,

125
00:09:15,445 --> 00:09:18,745
and also timestamps here.

126
00:09:18,745 --> 00:09:23,560
The timestamps allow you to have two different fields in

127
00:09:23,560 --> 00:09:28,850
the document: the created at field and the updated at field,

128
00:09:28,850 --> 00:09:38,200
both of which are timestamps stored in the form of an ISO date string in the document.

129
00:09:38,200 --> 00:09:43,615
Now, the rating itself would be an integer value.

130
00:09:43,615 --> 00:09:46,400
So, in Mongoose terminology,

131
00:09:46,400 --> 00:09:48,755
it will be stored as a number,

132
00:09:48,755 --> 00:09:50,680
the type would be a number.

133
00:09:50,680 --> 00:09:53,660
You can even specify the minimum and the maximum value.

134
00:09:53,660 --> 00:09:57,190
You can also specify that this particular field is required, so,

135
00:09:57,190 --> 00:10:04,460
which means that every document of the comment type should contain a rating field.

136
00:10:04,460 --> 00:10:07,370
Similarly, you can also define a comment field,

137
00:10:07,370 --> 00:10:08,710
which is of the type string.

138
00:10:08,710 --> 00:10:13,635
So, obviously, a comment is nothing but a string which contains some information,

139
00:10:13,635 --> 00:10:16,340
and this can also be defined as a required field,

140
00:10:16,340 --> 00:10:18,805
meaning that every document should contain a comment,

141
00:10:18,805 --> 00:10:21,060
and also an author field,

142
00:10:21,060 --> 00:10:22,800
which is also of the type string.

143
00:10:22,800 --> 00:10:28,030
So, you see that by defining this schema in this format.

144
00:10:28,030 --> 00:10:32,600
As we learned in the discussion a little bit earlier,

145
00:10:32,600 --> 00:10:41,890
schema is defined by using the various types that we have in our Mongoose application.

146
00:10:41,890 --> 00:10:43,030
So, in the schema, again,

147
00:10:43,030 --> 00:10:44,900
you see three different fields here,

148
00:10:44,900 --> 00:10:47,135
rating, comment, and author here,

149
00:10:47,135 --> 00:10:50,665
and each of which has a specific type given,

150
00:10:50,665 --> 00:10:53,060
and then whether this is required or not.

151
00:10:53,060 --> 00:10:56,505
So, thereby, you are imposing a strict structure

152
00:10:56,505 --> 00:11:01,320
on the comment documents that are going to be storing in your application.

153
00:11:01,320 --> 00:11:05,255
Now that we have defined a comment schema, we can then,

154
00:11:05,255 --> 00:11:12,254
as you noticed from the example of the kind of data that we require in our application,

155
00:11:12,254 --> 00:11:15,000
we have a dish document itself.

156
00:11:15,000 --> 00:11:17,620
The dish document contains various fields.

157
00:11:17,620 --> 00:11:19,050
Here, in the exercise,

158
00:11:19,050 --> 00:11:23,355
we will first introduce just two fields into the dish document,

159
00:11:23,355 --> 00:11:25,370
the name, and the description.

160
00:11:25,370 --> 00:11:27,010
In the next lesson,

161
00:11:27,010 --> 00:11:32,330
we will introduce the remaining fields for the dishSchema.

162
00:11:32,330 --> 00:11:33,680
Now, so the name,

163
00:11:33,680 --> 00:11:35,440
as in this case,

164
00:11:35,440 --> 00:11:36,765
is of the type string.

165
00:11:36,765 --> 00:11:39,450
We can also specify that this is a required field,

166
00:11:39,450 --> 00:11:43,360
meaning that every document should contain the name field.

167
00:11:43,360 --> 00:11:46,385
We can also specify that the name field is unique,

168
00:11:46,385 --> 00:11:53,215
meaning that no two documents can have exactly the same name value in the document.

169
00:11:53,215 --> 00:11:55,980
So, that ensures that each document will have

170
00:11:55,980 --> 00:12:01,300
a unique name field in it and a description field,

171
00:12:01,300 --> 00:12:03,115
which is again of the type string,

172
00:12:03,115 --> 00:12:06,460
but also specified as required.

173
00:12:06,460 --> 00:12:10,010
Now, as we saw in the example,

174
00:12:10,010 --> 00:12:15,750
a dish document contains multiple comments enclosed inside the document.

175
00:12:15,750 --> 00:12:20,920
Now, in Mongoose, this is supported through the use of sub-documents.

176
00:12:20,920 --> 00:12:24,230
So, if you define a schema earlier,

177
00:12:24,230 --> 00:12:27,345
so for example, we have already defined a commentSchema here,

178
00:12:27,345 --> 00:12:33,370
you can also define a field into another schema that you define and

179
00:12:33,370 --> 00:12:36,240
then specify that that field will be of

180
00:12:36,240 --> 00:12:39,520
the type of the previous schema that you have defined.

181
00:12:39,520 --> 00:12:40,960
So, in this case,

182
00:12:40,960 --> 00:12:44,360
the comments field, I am defining it as an array,

183
00:12:44,360 --> 00:12:51,545
so you see the use of an array type in your schema that you're defining here,

184
00:12:51,545 --> 00:12:55,110
and then array of the commentSchema type.

185
00:12:55,110 --> 00:13:00,725
So, this is an array of comments that will be included in each dish document.

186
00:13:00,725 --> 00:13:02,590
So, thereby, you can have

187
00:13:02,590 --> 00:13:11,640
more than one comment sub-document enclosed inside a dish document.

188
00:13:11,640 --> 00:13:16,080
So, defining the structure like this enables us to support

189
00:13:16,080 --> 00:13:20,950
the corresponding JSON string structure that we have defined

190
00:13:20,950 --> 00:13:26,470
for a dish document or that we have seen in the example earlier.

191
00:13:26,470 --> 00:13:30,145
Now, once we define the schema,

192
00:13:30,145 --> 00:13:33,695
to make use of this in our application,

193
00:13:33,695 --> 00:13:38,600
we need to create a model from that schema that we have just defined.

194
00:13:38,600 --> 00:13:40,640
So, within our application,

195
00:13:40,640 --> 00:13:45,320
we will define a Mongoose model and specify that the model

196
00:13:45,320 --> 00:13:51,085
is off the type dishSchema in this example.

197
00:13:51,085 --> 00:13:54,830
Not only that, you will also give a name to the model here.

198
00:13:54,830 --> 00:13:57,100
So, when you give a name to the model here,

199
00:13:57,100 --> 00:14:00,000
we are specifying the name as dish.

200
00:14:00,000 --> 00:14:03,860
Now, when you use this dish model in

201
00:14:03,860 --> 00:14:07,870
our node application where we are making use of Mongoose,

202
00:14:07,870 --> 00:14:15,280
then this will be transformed and mapped into a collection in my MongoDB database.

203
00:14:15,280 --> 00:14:18,885
The collection itself will be named as dishes.

204
00:14:18,885 --> 00:14:23,355
So, Mongoose automatically knows that when you specify a name here,

205
00:14:23,355 --> 00:14:27,990
it'll automatically construct the plural

206
00:14:27,990 --> 00:14:31,635
of that name and then give the collection the name,

207
00:14:31,635 --> 00:14:37,160
which is the plural of the model name that you specify in this example here.

208
00:14:37,160 --> 00:14:39,400
So, when I say dish here,

209
00:14:39,400 --> 00:14:42,620
then Mongoose automatically will map this into

210
00:14:42,620 --> 00:14:46,365
the dishes collection in the MongoDB database.

211
00:14:46,365 --> 00:14:53,385
How does it know how to convert this singular name to a plural?

212
00:14:53,385 --> 00:14:56,750
Mongoose automatically has a built-in mechanism that

213
00:14:56,750 --> 00:15:01,795
enables it to construct the plurals of standard English words.

214
00:15:01,795 --> 00:15:02,965
So, if you say dish,

215
00:15:02,965 --> 00:15:04,170
it will construct dishes.

216
00:15:04,170 --> 00:15:08,880
If you say leader, it will construct the plural of it as leaders, and so on.

217
00:15:08,880 --> 00:15:13,250
So, this is already built into the Mongoose node module.

218
00:15:13,250 --> 00:15:17,585
So, that is why when I specify this as a dish model type,

219
00:15:17,585 --> 00:15:24,050
then Mongoose will construct the dishes collection in my MongoDB database,

220
00:15:24,050 --> 00:15:27,155
and then that dishes collection will store

221
00:15:27,155 --> 00:15:33,050
the various documents of the dish type in there.

222
00:15:33,050 --> 00:15:35,780
Once we have created that, typically,

223
00:15:35,780 --> 00:15:38,150
when we declare models in our application,

224
00:15:38,150 --> 00:15:43,780
we would store them in a sub-folder named models, just for convenience.

225
00:15:43,780 --> 00:15:44,900
You don't need to do that,

226
00:15:44,900 --> 00:15:47,320
but just to organize your application,

227
00:15:47,320 --> 00:15:50,635
we would normally store that in a folder named models.

228
00:15:50,635 --> 00:15:55,010
Then the schema and the model would be

229
00:15:55,010 --> 00:15:59,470
defined in a file like this as you see in the example here,

230
00:15:59,470 --> 00:16:05,230
this called dishes.js, and then this would be exported because this is a node module.

231
00:16:05,230 --> 00:16:10,970
This'll be exported from this file so that it can be included into the node application,

232
00:16:10,970 --> 00:16:13,100
where we are going to make use of

233
00:16:13,100 --> 00:16:16,620
this schema and the model that we have just defined here.

234
00:16:16,620 --> 00:16:20,540
With this quick understanding of schema and model and

235
00:16:20,540 --> 00:16:26,370
its use in defining the structure for a document that we store in a MongoDB,

236
00:16:26,370 --> 00:16:33,510
let's go back and understand a little more about what Mongoose provides for us.

237
00:16:33,510 --> 00:16:39,965
In addition, Mongoose enables us to establish the connection with the MongoDB server.

238
00:16:39,965 --> 00:16:43,070
Mongoose internally make use of

239
00:16:43,070 --> 00:16:46,495
the MongoDB driver that we had used in the previous exercise.

240
00:16:46,495 --> 00:16:49,745
So, Mongoose depends upon the MongoDB driver, so,

241
00:16:49,745 --> 00:16:53,824
which means that from your Mongoose-based node application,

242
00:16:53,824 --> 00:16:56,960
you can use all the methods that are already

243
00:16:56,960 --> 00:17:01,040
available from the MongoDB driver also if you choose to,

244
00:17:01,040 --> 00:17:05,390
but Mongoose itself has its own collection of methods that we

245
00:17:05,390 --> 00:17:09,940
can make use of to interact with the MongoDB database,

246
00:17:09,940 --> 00:17:13,645
as we will see in the exercise that follows.

247
00:17:13,645 --> 00:17:19,040
Let me briefly show you how we would establish a connection to the database,

248
00:17:19,040 --> 00:17:21,590
and you will do this in the exercise that follows.

249
00:17:21,590 --> 00:17:25,280
So, just like we declared the URL in case

250
00:17:25,280 --> 00:17:29,160
of the MongoDB node application in the earlier lesson,

251
00:17:29,160 --> 00:17:32,630
we will still declare the URL for our application.

252
00:17:32,630 --> 00:17:36,965
Then we will use the Mongoose connect method

253
00:17:36,965 --> 00:17:40,180
and supply the URL for the Mongoose connect method,

254
00:17:40,180 --> 00:17:44,000
and this will establish the connection to the database.

255
00:17:44,000 --> 00:17:48,590
With this quick understanding of Mongoose and what role Mongoose

256
00:17:48,590 --> 00:17:53,485
plays in supporting structured insertion,

257
00:17:53,485 --> 00:17:58,985
storage, and retrieval of documents from our MongoDB,

258
00:17:58,985 --> 00:18:02,180
let's move on to the exercise where we will

259
00:18:02,180 --> 00:18:07,920
get some hands-on experience using the Mongoose module.