﻿1
00:00:00,980 --> 00:00:02,560
‫In this video, we're gonna use

2
00:00:02,560 --> 00:00:05,490
‫a simple trick in order to prevent users

3
00:00:05,490 --> 00:00:08,750
‫from writing multiple reviews for the same tours,

4
00:00:08,750 --> 00:00:11,323
‫so basically preventing duplicate reviews.

5
00:00:12,930 --> 00:00:16,140
‫So in the last video, we created all these reviews

6
00:00:16,140 --> 00:00:18,500
‫in order to calculate the averages.

7
00:00:18,500 --> 00:00:21,400
‫And we created multiple reviews for one tour,

8
00:00:21,400 --> 00:00:23,630
‫but all from the same user.

9
00:00:23,630 --> 00:00:27,590
‫But in practice, that doesn't make much sense, right?

10
00:00:27,590 --> 00:00:29,700
‫So in the real world, each user

11
00:00:29,700 --> 00:00:32,510
‫should only review each tour once.

12
00:00:32,510 --> 00:00:35,670
‫So basically, a duplicate review happens

13
00:00:35,670 --> 00:00:38,330
‫when there is a review with the same user

14
00:00:38,330 --> 00:00:40,060
‫and the same tour ID.

15
00:00:40,060 --> 00:00:43,580
‫And that's what we want to avoid from happening.

16
00:00:43,580 --> 00:00:45,410
‫And the obvious solution here is

17
00:00:45,410 --> 00:00:48,470
‫to just use a unique index, right?

18
00:00:48,470 --> 00:00:50,780
‫However, it is not enough to set

19
00:00:50,780 --> 00:00:53,120
‫both these fields to unique.

20
00:00:53,120 --> 00:00:55,770
‫And actually that would really be very wrong,

21
00:00:55,770 --> 00:01:00,240
‫because that would mean that each tour can get only review,

22
00:01:00,240 --> 00:01:03,570
‫and each user can only write one review.

23
00:01:03,570 --> 00:01:06,150
‫And obviously that's not what we want.

24
00:01:06,150 --> 00:01:09,900
‫So what we do need is them both together to be unique,

25
00:01:09,900 --> 00:01:14,150
‫so the combination of user and tour to be always unique.

26
00:01:14,150 --> 00:01:17,460
‫So that sounds a bit complicated, but luckily for us,

27
00:01:17,460 --> 00:01:21,170
‫that's actually very easy to achieve with indexes.

28
00:01:21,170 --> 00:01:24,860
‫So we already created a compound index on the tour before,

29
00:01:24,860 --> 00:01:27,523
‫and so now let's do the same here on the reviews.

30
00:01:28,660 --> 00:01:32,400
‫So again, right here after the schema definition,

31
00:01:32,400 --> 00:01:36,513
‫and of course we're still in the review model, right?

32
00:01:38,210 --> 00:01:41,450
‫So review, and that's not correct,

33
00:01:41,450 --> 00:01:44,800
‫so review schema dot index...

34
00:01:47,740 --> 00:01:51,530
‫Tour set to one, and once more it's not really important

35
00:01:51,530 --> 00:01:53,563
‫if it's one or minus one in this case.

36
00:01:55,310 --> 00:01:58,180
‫And user also set to one, okay.

37
00:01:58,180 --> 00:02:00,940
‫And so again, that's similar to what we did before,

38
00:02:00,940 --> 00:02:03,980
‫but here we're going to take it to the next level

39
00:02:03,980 --> 00:02:07,140
‫and now add an object for options.

40
00:02:07,140 --> 00:02:10,109
‫And the option here that we're gonna set is unique

41
00:02:10,109 --> 00:02:11,350
‫(typing)

42
00:02:11,350 --> 00:02:12,373
‫set to true.

43
00:02:15,010 --> 00:02:16,240
‫And that's actually it.

44
00:02:16,240 --> 00:02:18,700
‫This will achieve exactly what we want.

45
00:02:18,700 --> 00:02:21,290
‫So now each combination of tour and user

46
00:02:21,290 --> 00:02:22,903
‫has always to be unique.

47
00:02:23,780 --> 00:02:26,050
‫So let's give it a save here, or two,

48
00:02:26,050 --> 00:02:29,640
‫and then go test this out actually.

49
00:02:29,640 --> 00:02:31,360
‫Now when I first tested this,

50
00:02:31,360 --> 00:02:33,550
‫it actually didn't work right away.

51
00:02:33,550 --> 00:02:36,530
‫Really, it only just started working the next day,

52
00:02:36,530 --> 00:02:39,610
‫and I'm not really sure why, but if that happens to you,

53
00:02:39,610 --> 00:02:41,910
‫then don't worry about that, okay.

54
00:02:41,910 --> 00:02:43,840
‫And maybe it might even happen now

55
00:02:43,840 --> 00:02:45,240
‫as I'm recording this video.

56
00:02:46,080 --> 00:02:49,970
‫So anyway, right now, there should not be any reviews

57
00:02:49,970 --> 00:02:51,963
‫on the tour that we were working on.

58
00:02:52,810 --> 00:02:57,110
‫So just to make sure we still have zero ratings

59
00:02:57,110 --> 00:03:01,010
‫and also the reviews are empty.

60
00:03:01,010 --> 00:03:02,840
‫And so let's now once more create

61
00:03:02,840 --> 00:03:05,223
‫a new review on this tour.

62
00:03:06,720 --> 00:03:07,553
‫Okay.

63
00:03:09,800 --> 00:03:13,490
‫So this is one review, so one user and one review.

64
00:03:13,490 --> 00:03:17,660
‫So that of course should work, but if I now send this again

65
00:03:17,660 --> 00:03:22,000
‫and let's say I set it to four and say okay,

66
00:03:22,000 --> 00:03:25,290
‫then this should not be allowed to work, okay.

67
00:03:25,290 --> 00:03:27,310
‫Just keep in mind that it might still work

68
00:03:27,310 --> 00:03:30,170
‫because of the issue I was telling you before, okay.

69
00:03:30,170 --> 00:03:34,253
‫So sometimes this kind of index doesn't get set immediately.

70
00:03:35,850 --> 00:03:39,120
‫Oh, but actually, in my case here it worked right away.

71
00:03:39,120 --> 00:03:43,307
‫So we get this duplicate key error on this index here,

72
00:03:43,307 --> 00:03:47,210
‫and so that's exactly the index that we just created before.

73
00:03:47,210 --> 00:03:50,063
‫So let's take a look at that also here in Compass.

74
00:03:52,090 --> 00:03:54,153
‫So here it actually is not,

75
00:03:55,547 --> 00:03:57,970
‫and so I will do it just like I did before

76
00:03:57,970 --> 00:03:59,873
‫and reconnect basically.

77
00:04:04,210 --> 00:04:07,893
‫So going to the recents, then connecting here.

78
00:04:12,240 --> 00:04:13,360
‫Natours...

79
00:04:16,760 --> 00:04:17,593
‫Then...

80
00:04:19,390 --> 00:04:20,453
‫Of course the tours,

81
00:04:21,520 --> 00:04:24,690
‫and our indexes here are now these four.

82
00:04:24,690 --> 00:04:26,640
‫And so that's the one that we just created,

83
00:04:26,640 --> 00:04:29,920
‫or actually it's not (laughs), okay.

84
00:04:29,920 --> 00:04:32,290
‫So for some reason, it's not here,

85
00:04:32,290 --> 00:04:34,400
‫so that's just what I was saying earlier,

86
00:04:34,400 --> 00:04:38,083
‫but don't mind because actually it is working in our code.

87
00:04:39,840 --> 00:04:43,510
‫Okay, so we were not able to create two reviews

88
00:04:43,510 --> 00:04:46,220
‫coming from the same user, okay.

89
00:04:46,220 --> 00:04:48,480
‫But if you now log in as someone else,

90
00:04:48,480 --> 00:04:52,740
‫well, then we will certainly be able to post this review.

91
00:04:52,740 --> 00:04:55,530
‫So let's see what user we could use now.

92
00:04:55,530 --> 00:04:58,973
‫So let's get all users here,

93
00:05:01,160 --> 00:05:04,970
‫which I can't because I'm not an admin (laughs), okay.

94
00:05:04,970 --> 00:05:07,070
‫So I forgot about that part,

95
00:05:07,070 --> 00:05:10,500
‫and so I'm simply going to retrieve this from Compass.

96
00:05:10,500 --> 00:05:12,003
‫Sometimes that's just easier.

97
00:05:13,230 --> 00:05:15,410
‫So this is a guide, a user (exclaims),

98
00:05:15,410 --> 00:05:19,443
‫so let's just use this Eduardo here or something.

99
00:05:22,120 --> 00:05:26,943
‫So let's log in as this person, as this user.

100
00:05:31,120 --> 00:05:34,270
‫Yep, with success, and now we should be allowed

101
00:05:34,270 --> 00:05:39,000
‫to create a review, and indeed here it is, okay.

102
00:05:39,000 --> 00:05:40,483
‫And if we now update this,

103
00:05:41,720 --> 00:05:45,970
‫then we have our two ratings, great.

104
00:05:45,970 --> 00:05:48,620
‫Now just testing it again, so if we send it again,

105
00:05:48,620 --> 00:05:51,510
‫it's not going to work because again,

106
00:05:51,510 --> 00:05:53,530
‫we have a duplicate error.

107
00:05:53,530 --> 00:05:54,640
‫Awesome.

108
00:05:54,640 --> 00:05:57,110
‫There is just one more thing that I wanted to show you,

109
00:05:57,110 --> 00:06:00,693
‫and so for that, I'm going to log in as yet another person,

110
00:06:03,040 --> 00:06:07,300
‫okay, so that I can then create another review.

111
00:06:07,300 --> 00:06:10,523
‫So this time, I'm gonna be this Max Smith.

112
00:06:12,150 --> 00:06:14,203
‫And so let's log in.

113
00:06:17,140 --> 00:06:18,420
‫(mouse clicks)

114
00:06:18,420 --> 00:06:21,350
‫Okay, so now I'm officially Max,

115
00:06:21,350 --> 00:06:23,973
‫and I will be able to post this review.

116
00:06:27,500 --> 00:06:28,453
‫So with five,

117
00:06:30,840 --> 00:06:32,210
‫I'm able to do that,

118
00:06:32,210 --> 00:06:35,123
‫and now I want to take a look at the average.

119
00:06:36,080 --> 00:06:40,660
‫Okay, so right now it is this 4.6666,

120
00:06:40,660 --> 00:06:43,040
‫which of course does not look good.

121
00:06:43,040 --> 00:06:45,090
‫And we could fix this in the front end.

122
00:06:45,090 --> 00:06:47,330
‫For example when we request this data

123
00:06:47,330 --> 00:06:49,490
‫from the API and then display it,

124
00:06:49,490 --> 00:06:52,010
‫we could on the front end then do this rounding.

125
00:06:52,010 --> 00:06:55,260
‫But actually, I want to do it right here on the back end

126
00:06:55,260 --> 00:06:59,250
‫so that the end user already gets this final rounded value,

127
00:06:59,250 --> 00:07:02,980
‫which in this case would be 4.7, right?

128
00:07:02,980 --> 00:07:06,340
‫And for doing that, I'm gonna show you a small new feature

129
00:07:06,340 --> 00:07:09,230
‫in Mongoose that we didn't use yet.

130
00:07:09,230 --> 00:07:12,323
‫So let's go to our tour model,

131
00:07:13,220 --> 00:07:15,070
‫and to that average,

132
00:07:15,070 --> 00:07:16,410
‫so right here.

133
00:07:16,410 --> 00:07:19,132
‫And so now, we can use a setter function.

134
00:07:19,132 --> 00:07:21,100
‫(typing)

135
00:07:21,100 --> 00:07:24,070
‫So set and this function will be run each time

136
00:07:24,070 --> 00:07:27,257
‫that a new value is set for this field, okay.

137
00:07:27,257 --> 00:07:31,180
‫And so here, we usually specify a callback function,

138
00:07:31,180 --> 00:07:33,003
‫which receives the current value.

139
00:07:34,570 --> 00:07:37,610
‫And in this case, it returns basically this value,

140
00:07:37,610 --> 00:07:38,533
‫but rounded.

141
00:07:39,760 --> 00:07:44,760
‫So we use math dot round for the current value,

142
00:07:46,040 --> 00:07:48,610
‫but the problem with math dot round is that

143
00:07:48,610 --> 00:07:51,240
‫it rounds values to integers.

144
00:07:51,240 --> 00:07:54,253
‫So for example, if we had something like this,

145
00:07:55,412 --> 00:07:58,830
‫it would then round this to five, okay.

146
00:07:58,830 --> 00:08:00,410
‫And that's not what we want.

147
00:08:00,410 --> 00:08:03,610
‫We want it to be rounded to 4.7.

148
00:08:03,610 --> 00:08:05,310
‫And so we're gonna use a trick here,

149
00:08:05,310 --> 00:08:10,037
‫which is quite common, so multiplying this by 10,

150
00:08:10,037 --> 00:08:13,647
‫and so with that, we would get 46.666,

151
00:08:14,580 --> 00:08:17,960
‫and then this rounded would be 47.

152
00:08:17,960 --> 00:08:21,120
‫And so then, we divide the results by 10 again,

153
00:08:21,120 --> 00:08:22,810
‫and that then is 4.7.

154
00:08:26,470 --> 00:08:29,180
‫All right, and that's actually it.

155
00:08:29,180 --> 00:08:31,790
‫So again, a setter function here which is going

156
00:08:31,790 --> 00:08:34,710
‫to be run each time that there is a new value

157
00:08:34,710 --> 00:08:36,903
‫for the ratings average field.

158
00:08:38,640 --> 00:08:42,650
‫So just to test this, let's actually simply

159
00:08:42,650 --> 00:08:45,743
‫update this last review that we added,

160
00:08:49,080 --> 00:08:52,030
‫which had a five, and let's keep it at five.

161
00:08:52,030 --> 00:08:54,830
‫So all we basically want to do is to re-run

162
00:08:54,830 --> 00:08:57,283
‫that function which creates this average.

163
00:08:59,490 --> 00:09:02,910
‫So if I do this now and now get my tour,

164
00:09:02,910 --> 00:09:05,853
‫we should get 4.7 here as the average.

165
00:09:06,780 --> 00:09:09,620
‫And yep, here we go.

166
00:09:09,620 --> 00:09:13,210
‫Great, and that's actually it already for this video.

167
00:09:13,210 --> 00:09:15,940
‫So we created this nice setter function,

168
00:09:15,940 --> 00:09:18,940
‫and we created this unique compound index here

169
00:09:18,940 --> 00:09:21,000
‫in order to ensure that one user

170
00:09:21,000 --> 00:09:24,053
‫cannot write multiple reviews for the same tour.

