﻿1
00:00:01,060 --> 00:00:03,880
‫Welcome back to the next video.

2
00:00:03,880 --> 00:00:05,834
‫And let's keep it going now with a new

3
00:00:05,834 --> 00:00:08,409
‫and pretty advanced Mongoose feature

4
00:00:08,409 --> 00:00:10,917
‫called 'Virtual Populate.'

5
00:00:12,410 --> 00:00:14,441
‫So, at the point, we have populated

6
00:00:14,441 --> 00:00:16,220
‫the reviews with the tour and

7
00:00:16,220 --> 00:00:20,940
‫the user data right here, right?

8
00:00:20,940 --> 00:00:22,516
‫And so, right now, when we query for reviews,

9
00:00:22,516 --> 00:00:26,160
‫we get access to that information.

10
00:00:26,160 --> 00:00:29,086
‫However, that still leaves one problem unsolved.

11
00:00:29,086 --> 00:00:33,290
‫So, how are we going to access reviews on the tours?

12
00:00:33,290 --> 00:00:34,936
‫So basically, the other way around.

13
00:00:34,936 --> 00:00:38,380
‫So, let's say that I queried for a specific tour.

14
00:00:38,380 --> 00:00:39,766
‫And then, how will I get access

15
00:00:39,766 --> 00:00:42,306
‫to all the reviews for that tour?

16
00:00:42,306 --> 00:00:44,803
‫And this problem arises here because

17
00:00:44,803 --> 00:00:47,357
‫we did parent referencing on the reviews.

18
00:00:47,357 --> 00:00:50,676
‫So basically, having the reviews pointing to the tours

19
00:00:50,676 --> 00:00:54,350
‫and not the tours pointing to the reviews.

20
00:00:54,350 --> 00:00:57,180
‫And so, as we said in the beginning of the section,

21
00:00:57,180 --> 00:00:58,660
‫in this case, the parent does not

22
00:00:58,660 --> 00:01:01,560
‫really know about its children.

23
00:01:01,560 --> 00:01:03,060
‫And so, in this example,

24
00:01:03,060 --> 00:01:06,480
‫the tour does not know about its reviews.

25
00:01:06,480 --> 00:01:08,170
‫And sometimes, that's okay.

26
00:01:08,170 --> 00:01:10,750
‫But in this case, we actually want the tour

27
00:01:10,750 --> 00:01:14,790
‫to basically know about all the reviews that it's got.

28
00:01:14,790 --> 00:01:16,470
‫Now, in order to solve this,

29
00:01:16,470 --> 00:01:18,110
‫with what we know at this point,

30
00:01:18,110 --> 00:01:20,330
‫we could have two solutions.

31
00:01:20,330 --> 00:01:23,050
‫And the first one would be to manually query

32
00:01:23,050 --> 00:01:26,570
‫for reviews each time that we query for tours.

33
00:01:26,570 --> 00:01:28,106
‫But it would be a bit cumbersome

34
00:01:28,106 --> 00:01:30,550
‫doing it manually like this.

35
00:01:30,550 --> 00:01:33,440
‫And the second solution could be to also

36
00:01:33,440 --> 00:01:35,860
‫do child referencing on the tours.

37
00:01:35,860 --> 00:01:37,810
‫So basically, keep an array of all

38
00:01:37,810 --> 00:01:40,460
‫the review ID's on each tour document.

39
00:01:40,460 --> 00:01:42,100
‫Then, all we would have to do

40
00:01:42,100 --> 00:01:45,020
‫is to populate that array, right?

41
00:01:45,020 --> 00:01:47,513
‫But, we actually already ruled out doing this

42
00:01:47,513 --> 00:01:49,341
‫right in the beginning because

43
00:01:49,341 --> 00:01:51,751
‫we do not want to store that array

44
00:01:51,751 --> 00:01:53,785
‫of review ID's that could then grow

45
00:01:53,785 --> 00:01:57,190
‫indefinitely in our database, right?

46
00:01:57,190 --> 00:01:59,770
‫And that's actually exactly why we picked

47
00:01:59,770 --> 00:02:02,243
‫parent referencing in the first place.

48
00:02:02,243 --> 00:02:05,450
‫However, there is great solution for this.

49
00:02:05,450 --> 00:02:08,040
‫And that's because Mongoose actually offers us

50
00:02:08,040 --> 00:02:10,054
‫a very nice solution for this problem

51
00:02:10,054 --> 00:02:14,930
‫with a pretty advanced feature called 'Virtual Populate.'

52
00:02:14,930 --> 00:02:16,809
‫So with 'Virtual Populate,' we can actually

53
00:02:16,809 --> 00:02:20,020
‫populate the tour with reviews.

54
00:02:20,020 --> 00:02:21,503
‫So, in other words, we can get access

55
00:02:21,503 --> 00:02:24,624
‫to all the reviews for a certain tour,

56
00:02:24,624 --> 00:02:29,624
‫but without keeping this array of ID's on the tour.

57
00:02:29,850 --> 00:02:31,535
‫So, think of 'Virtual Populate' like a way

58
00:02:31,535 --> 00:02:35,316
‫of keeping that array of review ID's on a tour,

59
00:02:35,316 --> 00:02:39,750
‫but without actually persisting it to the database.

60
00:02:39,750 --> 00:02:41,916
‫And so that then solves the problem that we have

61
00:02:41,916 --> 00:02:44,790
‫with child referencing, right?

62
00:02:44,790 --> 00:02:49,490
‫So, it's a bit like virtual fields, but with populate, okay?

63
00:02:49,490 --> 00:02:51,030
‫So, just to illustrate that,

64
00:02:51,030 --> 00:02:54,030
‫let's go to our tour model here.

65
00:02:54,030 --> 00:02:56,430
‫And so, what I just described would be,

66
00:02:56,430 --> 00:02:59,310
‫in theory, to do something like this.

67
00:02:59,310 --> 00:03:00,670
‫So, on our tour model,

68
00:03:00,670 --> 00:03:03,447
‫we would add a field called 'Reviews.'

69
00:03:03,447 --> 00:03:06,114
‫(keys clicking)

70
00:03:07,050 --> 00:03:11,371
‫And then set the type to Mongoose.Schema.ObjectId.

71
00:03:11,371 --> 00:03:13,782
‫(keys clicking)

72
00:03:13,782 --> 00:03:15,910
‫And you don't need to write this.

73
00:03:15,910 --> 00:03:18,629
‫I'm just doing it to show it to you.

74
00:03:18,629 --> 00:03:20,920
‫(keys clicking)

75
00:03:20,920 --> 00:03:24,710
‫And then connect it with 'Review.'

76
00:03:24,710 --> 00:03:28,683
‫And of course, this here would have to be an object.

77
00:03:28,683 --> 00:03:31,763
‫But, what matters here is that this is basically

78
00:03:31,763 --> 00:03:35,100
‫how we would implement child referencing.

79
00:03:35,100 --> 00:03:38,150
‫So the tour referencing reviews, okay?

80
00:03:38,150 --> 00:03:40,174
‫But again, we do not want to do it.

81
00:03:40,174 --> 00:03:43,848
‫So instead, we're going to implement 'Virtual Populate.'

82
00:03:43,848 --> 00:03:45,980
‫(keys clicking)

83
00:03:45,980 --> 00:03:48,480
‫All right. And it works like this.

84
00:03:48,480 --> 00:03:52,337
‫So we do it here on the tour schema.

85
00:03:52,337 --> 00:03:54,470
‫(keys clicking)

86
00:03:54,470 --> 00:03:57,000
‫And we still do it .virtual.

87
00:03:57,000 --> 00:04:00,283
‫So just like with this virtual field here, duration week,

88
00:04:00,283 --> 00:04:04,158
‫then we type in the name of the virtual field.

89
00:04:04,158 --> 00:04:05,936
‫So let's call it 'Reviews,'

90
00:04:05,936 --> 00:04:10,450
‫and then an object of some options.

91
00:04:10,450 --> 00:04:12,017
‫And the first one is the name of the model

92
00:04:12,017 --> 00:04:14,030
‫that we want to reference.

93
00:04:14,030 --> 00:04:16,850
‫And so that works just like with the normal referencing.

94
00:04:16,850 --> 00:04:18,920
‫(keys clicking)

95
00:04:18,920 --> 00:04:21,360
‫So again, the name of the model.

96
00:04:21,360 --> 00:04:23,580
‫So, 'Review' or course, in this case.

97
00:04:23,580 --> 00:04:26,490
‫And now, we actually need to specify the name of the fields

98
00:04:26,490 --> 00:04:29,320
‫in order to connect the two data sets.

99
00:04:29,320 --> 00:04:31,570
‫And this is, for me, the most complicated part

100
00:04:31,570 --> 00:04:33,810
‫of implementing this 'Virtual Populate.'

101
00:04:33,810 --> 00:04:37,420
‫And so, let's make sure you really understand this part.

102
00:04:37,420 --> 00:04:39,880
‫So here, we need to specify two fields.

103
00:04:39,880 --> 00:04:42,166
‫The foreign field and the local field.

104
00:04:42,166 --> 00:04:46,940
‫So let us start with the foreign field.

105
00:04:46,940 --> 00:04:49,990
‫And so, this is the name of the field in the other model.

106
00:04:49,990 --> 00:04:51,636
‫So in the Review model in this case,

107
00:04:51,636 --> 00:04:54,940
‫where the reference to the current model is stored.

108
00:04:54,940 --> 00:04:59,050
‫And that is, in this case, the Tour field, right?

109
00:04:59,050 --> 00:05:00,396
‫So, let's take look at that.

110
00:05:00,396 --> 00:05:02,867
‫And so, again, in our review model,

111
00:05:02,867 --> 00:05:05,490
‫we have a field called 'Tour.'

112
00:05:05,490 --> 00:05:08,940
‫And so this is where the ID of the tour is being stored.

113
00:05:08,940 --> 00:05:11,442
‫And so that's why here, in this foreign field,

114
00:05:11,442 --> 00:05:14,111
‫we specify that name of that field

115
00:05:14,111 --> 00:05:17,720
‫in order to connect these two models, okay?

116
00:05:17,720 --> 00:05:20,220
‫And now we need to do the same for the current model.

117
00:05:20,220 --> 00:05:23,060
‫So, we need to say where that ID is actually stored

118
00:05:23,060 --> 00:05:25,773
‫here in this current Tour model.

119
00:05:26,720 --> 00:05:27,883
‫So, local field.

120
00:05:29,520 --> 00:05:32,090
‫And that is, the ID.

121
00:05:32,090 --> 00:05:34,600
‫So, _ID, okay?

122
00:05:34,600 --> 00:05:37,368
‫And so, again, this _ID, which is how

123
00:05:37,368 --> 00:05:39,285
‫it's called in the local model,

124
00:05:39,285 --> 00:05:42,400
‫is called 'Tour' in the foreign model.

125
00:05:42,400 --> 00:05:45,070
‫So, in the Review model. Okay?

126
00:05:45,070 --> 00:05:47,020
‫And so again, this is how we connect

127
00:05:47,020 --> 00:05:48,763
‫these two models together.

128
00:05:49,690 --> 00:05:51,750
‫Let's us write here that this is

129
00:05:51,750 --> 00:05:55,223
‫'Virtual Populate,' okay?

130
00:05:56,230 --> 00:05:58,580
‫And so now, with this setup, we can actually use

131
00:05:58,580 --> 00:06:01,260
‫Populate just like we did before.

132
00:06:01,260 --> 00:06:03,370
‫And so what we want to do now is to go ahead

133
00:06:03,370 --> 00:06:05,475
‫and populate the tour when we only

134
00:06:05,475 --> 00:06:08,860
‫get one single tour, okay?

135
00:06:08,860 --> 00:06:13,860
‫So here in Postman, it is in this situation of 'Get Tour.'

136
00:06:14,130 --> 00:06:16,830
‫Okay? Let's see of this actually exists.

137
00:06:16,830 --> 00:06:19,963
‫And it does, but it's this weird test tour.

138
00:06:21,490 --> 00:06:25,933
‫And so, let's actually do it with this 'Forest Hiker' one.

139
00:06:29,101 --> 00:06:30,033
‫All right.

140
00:06:32,380 --> 00:06:33,980
‫So, when we get this tour,

141
00:06:33,980 --> 00:06:36,080
‫we now want to populate the reviews.

142
00:06:36,080 --> 00:06:39,073
‫And it should already be here as an empty array.

143
00:06:39,980 --> 00:06:41,220
‫Ah, here it is.

144
00:06:41,220 --> 00:06:43,810
‫It's not an empty array, but it's set to 'null.'

145
00:06:43,810 --> 00:06:45,540
‫But the virtual field is actually

146
00:06:45,540 --> 00:06:47,450
‫already there with the reviews.

147
00:06:47,450 --> 00:06:49,160
‫But it's null at this point because

148
00:06:49,160 --> 00:06:51,830
‫we didn't yet populate it, okay?

149
00:06:51,830 --> 00:06:53,800
‫And again, we only want to populate it

150
00:06:53,800 --> 00:06:54,940
‫here in the 'Get One Tour,' and not

151
00:06:54,940 --> 00:06:57,360
‫in the 'Get All Tours' because that

152
00:06:57,360 --> 00:06:59,319
‫would be a bit too much information to send

153
00:06:59,319 --> 00:07:03,250
‫down to a client when they get all the tours.

154
00:07:03,250 --> 00:07:05,350
‫Also, when we're getting all the tours,

155
00:07:05,350 --> 00:07:08,030
‫that's usually to build an overview page.

156
00:07:08,030 --> 00:07:09,340
‫And in that case, we usually

157
00:07:09,340 --> 00:07:12,000
‫do not need access to all the reviews.

158
00:07:12,000 --> 00:07:13,440
‫We only need that when we are

159
00:07:13,440 --> 00:07:15,600
‫really displaying just one tour.

160
00:07:15,600 --> 00:07:17,080
‫Okay? And so, I think it makes sense

161
00:07:17,080 --> 00:07:20,117
‫to only do this populate on 'Get One Tour.'

162
00:07:21,060 --> 00:07:23,010
‫So, let's do that populate actually

163
00:07:23,010 --> 00:07:24,803
‫right in the controller.

164
00:07:24,803 --> 00:07:27,543
‫So, the tour controller and down here

165
00:07:27,543 --> 00:07:31,010
‫where we have 'Get Tour.'

166
00:07:31,010 --> 00:07:33,473
‫And so, that's actually very easy.

167
00:07:33,473 --> 00:07:36,624
‫Only to do is to call 'Populate' after the other query,

168
00:07:36,624 --> 00:07:40,670
‫and then simply pass the name

169
00:07:40,670 --> 00:07:42,850
‫of the field that we want to populate.

170
00:07:42,850 --> 00:07:45,803
‫And so, as we already know, that is called 'Reviews.'

171
00:07:45,803 --> 00:07:48,613
‫And, so that should actually be it already.

172
00:07:50,520 --> 00:07:51,460
‫All right?

173
00:07:51,460 --> 00:07:54,573
‫So, let's test this now, and take a look at this.

174
00:07:57,500 --> 00:08:02,010
‫And indeed, we now get our complete review right here.

175
00:08:02,010 --> 00:08:04,570
‫All right? So that got populated.

176
00:08:04,570 --> 00:08:07,160
‫And so it means that our Virtual Populate

177
00:08:07,160 --> 00:08:09,130
‫is actually working.

178
00:08:09,130 --> 00:08:10,913
‫Now, you might start to see that

179
00:08:10,913 --> 00:08:12,752
‫this is creating kind of a problem

180
00:08:12,752 --> 00:08:15,166
‫because this here is basically creating

181
00:08:15,166 --> 00:08:17,410
‫a chain of populates.

182
00:08:17,410 --> 00:08:19,400
‫And that's not ideal at all.

183
00:08:19,400 --> 00:08:22,690
‫So, we have the tour being populated with reviews.

184
00:08:22,690 --> 00:08:24,950
‫But then the reviews also get populated

185
00:08:24,950 --> 00:08:28,100
‫with the tour again, and also with the user.

186
00:08:28,100 --> 00:08:30,280
‫And then also the tour is also

187
00:08:30,280 --> 00:08:32,270
‫getting populated with guides.

188
00:08:32,270 --> 00:08:34,160
‫Which in this case, is not happening

189
00:08:34,160 --> 00:08:35,820
‫because there are no guides.

190
00:08:35,820 --> 00:08:38,770
‫But if there were, then we would have yet another populate.

191
00:08:38,770 --> 00:08:41,618
‫And so here we would have a chain of three populates.

192
00:08:41,618 --> 00:08:45,360
‫And so for performance, that's of course, not ideal at all.

193
00:08:45,360 --> 00:08:47,500
‫Especially here with the tour.

194
00:08:47,500 --> 00:08:49,860
‫So we have the tour populated with reviews.

195
00:08:49,860 --> 00:08:52,660
‫And in the reviews, we again have the data about the tour.

196
00:08:52,660 --> 00:08:55,550
‫And so that doesn't make much sense at all.

197
00:08:55,550 --> 00:08:57,430
‫So, it's kind of a mess now.

198
00:08:57,430 --> 00:08:59,830
‫SO, the solution that I'm going to use here

199
00:08:59,830 --> 00:09:01,408
‫is to actually turn off populating

200
00:09:01,408 --> 00:09:04,710
‫the reviews with the tours, okay?

201
00:09:04,710 --> 00:09:09,460
‫So basically, we do not need this data here on each review.

202
00:09:09,460 --> 00:09:11,950
‫So in this case, I think that's a good solution.

203
00:09:11,950 --> 00:09:14,370
‫But of course, again in your case,

204
00:09:14,370 --> 00:09:15,920
‫it will always depend on how

205
00:09:15,920 --> 00:09:18,077
‫your application works in your specific case.

206
00:09:18,077 --> 00:09:21,140
‫But in this app, it's more logical to

207
00:09:21,140 --> 00:09:23,357
‫really have the reviews available on tours,

208
00:09:23,357 --> 00:09:25,790
‫and it's not that important having the tour

209
00:09:25,790 --> 00:09:28,750
‫available on the review, okay?

210
00:09:28,750 --> 00:09:32,010
‫So, let's turn that populate off basically,

211
00:09:32,010 --> 00:09:33,513
‫in the Review model.

212
00:09:35,620 --> 00:09:36,640
‫Okay?

213
00:09:36,640 --> 00:09:39,573
‫So, let's just comment this part out,

214
00:09:40,490 --> 00:09:41,823
‫copy it down here,

215
00:09:44,670 --> 00:09:48,253
‫and so, basically get rid of this first one.

216
00:09:50,530 --> 00:09:51,420
‫Now all right?

217
00:09:51,420 --> 00:09:52,620
‫Get ready to save.

218
00:09:52,620 --> 00:09:53,790
‫Let's try it again.

219
00:09:53,790 --> 00:09:57,083
‫And so, now we should only see the ID of the tour here.

220
00:09:59,670 --> 00:10:02,800
‫Okay? And indeed, that's exactly what we get.

221
00:10:02,800 --> 00:10:04,627
‫Okay? Now with this, of course,

222
00:10:04,627 --> 00:10:07,603
‫we still do parent referencing, okay?

223
00:10:07,603 --> 00:10:10,648
‫We still keep a reference to the tours here,

224
00:10:10,648 --> 00:10:13,100
‫but we simply do not populate it.

225
00:10:13,100 --> 00:10:14,920
‫And again, because we don't always

226
00:10:14,920 --> 00:10:16,749
‫need that data right here.

227
00:10:16,749 --> 00:10:20,970
‫All right. Let's just quickly recap what we did here.

228
00:10:20,970 --> 00:10:24,698
‫So, we started doing only parent referencing on the review.

229
00:10:24,698 --> 00:10:26,853
‫But that made it so that on the tours,

230
00:10:26,853 --> 00:10:30,360
‫we had no access to its corresponding reviews.

231
00:10:30,360 --> 00:10:32,350
‫And the easiest fix for that would be

232
00:10:32,350 --> 00:10:35,090
‫to also do child referencing on the tours.

233
00:10:35,090 --> 00:10:36,740
‫But the problem with that would be

234
00:10:36,740 --> 00:10:39,000
‫that we do not actually want to keep

235
00:10:39,000 --> 00:10:40,801
‫an array of all the child documents

236
00:10:40,801 --> 00:10:43,310
‫on the parent document, right?

237
00:10:43,310 --> 00:10:44,993
‫Because again, we don't want to allow

238
00:10:44,993 --> 00:10:47,960
‫arrays to grow indefinitely.

239
00:10:47,960 --> 00:10:49,050
‫So instead of doing that,

240
00:10:49,050 --> 00:10:52,853
‫we implemented virtual populates like this.

241
00:10:54,279 --> 00:10:56,100
‫All right? So, just like this.

242
00:10:56,100 --> 00:10:59,340
‫And this allows us to basically do the exact same thing.

243
00:10:59,340 --> 00:11:01,940
‫So, keeping a reference to all the child documents

244
00:11:01,940 --> 00:11:03,049
‫on the parent document,

245
00:11:03,049 --> 00:11:05,911
‫but without actually persisting that information

246
00:11:05,911 --> 00:11:07,970
‫to the database.

247
00:11:07,970 --> 00:11:11,002
‫And so then, after having this virtual populate set up,

248
00:11:11,002 --> 00:11:14,196
‫all we needed to do is to basically use

249
00:11:14,196 --> 00:11:19,090
‫Populate just like we did before with the real references.

250
00:11:19,090 --> 00:11:20,668
‫And then, finally, we also turned off

251
00:11:20,668 --> 00:11:24,108
‫one of the populates that we had on the review.

252
00:11:24,108 --> 00:11:26,610
‫So, this one here, where we populated

253
00:11:26,610 --> 00:11:29,618
‫the tour ID, because that was creating

254
00:11:29,618 --> 00:11:33,230
‫an inefficient chain of populates.

255
00:11:33,230 --> 00:11:36,470
‫And so that's, of course, something that we do not want.

256
00:11:36,470 --> 00:11:38,430
‫And so, in the end, we ended up with

257
00:11:38,430 --> 00:11:43,070
‫a result like this, okay?

258
00:11:43,070 --> 00:11:43,903
‫Great.

259
00:11:43,903 --> 00:11:45,560
‫So, I hope that made sense to you.

260
00:11:45,560 --> 00:11:47,086
‫And so with this, we actually wrap up for now

261
00:11:47,086 --> 00:11:51,200
‫of this part of populating, okay?

262
00:11:51,200 --> 00:11:53,692
‫And so now let's move on to a next topic,

263
00:11:53,692 --> 00:11:56,783
‫which is basically creating nested routes.

