1
00:00:02,240 --> 00:00:04,890
So let's now come back to that example,

2
00:00:04,890 --> 00:00:08,000
which we briefly touched on over the last lectures

3
00:00:08,000 --> 00:00:10,410
and which we also used in the SQL,

4
00:00:10,410 --> 00:00:14,310
introduction section with the restaurants at the reviews.

5
00:00:14,310 --> 00:00:15,210
In the last lectures,

6
00:00:15,210 --> 00:00:18,100
of course I only added some basic restaurant data

7
00:00:18,100 --> 00:00:19,610
because I wanted to get started

8
00:00:19,610 --> 00:00:22,190
with the general MongoDB query syntax

9
00:00:22,190 --> 00:00:24,060
and the CORS operations,

10
00:00:24,060 --> 00:00:26,990
but now I want to discuss how we would really build

11
00:00:26,990 --> 00:00:29,760
such a restaurants and reviews application

12
00:00:29,760 --> 00:00:32,250
from a database point of view,

13
00:00:32,250 --> 00:00:34,693
when working with a no SQL database.

14
00:00:35,540 --> 00:00:37,020
And for that let's first of all,

15
00:00:37,020 --> 00:00:40,680
come back to what we did in the SQL sections

16
00:00:40,680 --> 00:00:43,723
in the SQL world, how that looked like there.

17
00:00:44,850 --> 00:00:48,950
And there, we ended up with this structure,

18
00:00:48,950 --> 00:00:52,810
we built four different tables, one for the restaurants,

19
00:00:52,810 --> 00:00:55,290
then one for the addresses of the restaurants

20
00:00:55,290 --> 00:00:56,850
and one for the types,

21
00:00:56,850 --> 00:01:00,380
and these tables were linked together through relations.

22
00:01:00,380 --> 00:01:02,090
And then we had the reviews table,

23
00:01:02,090 --> 00:01:06,020
which was also connected to restaurants, through a relation.

24
00:01:06,020 --> 00:01:08,960
And the idea here was that with SQL,

25
00:01:08,960 --> 00:01:11,050
we want to have those clear structures.

26
00:01:11,050 --> 00:01:13,530
We want to have those flat records

27
00:01:13,530 --> 00:01:15,900
and those normalized data records.

28
00:01:15,900 --> 00:01:19,490
And it's absolutely normal and wanted in the SQL world

29
00:01:19,490 --> 00:01:21,653
that we work with multiple tables.

30
00:01:22,810 --> 00:01:24,600
Now in the no SQL world,

31
00:01:24,600 --> 00:01:26,730
that's not the main idea.

32
00:01:26,730 --> 00:01:29,020
Instead as you learned before in this section

33
00:01:29,020 --> 00:01:31,000
with no SQL databases,

34
00:01:31,000 --> 00:01:35,290
you typically plan for the queries you are about to run

35
00:01:35,290 --> 00:01:36,910
in your application.

36
00:01:36,910 --> 00:01:39,910
So from your NodeJS server, so to say,

37
00:01:39,910 --> 00:01:43,440
and you want to store your data such that your queries

38
00:01:43,440 --> 00:01:46,280
can be as simple and efficient as possible

39
00:01:46,280 --> 00:01:48,083
when working with no SQL,

40
00:01:49,070 --> 00:01:52,210
therefore instead of setting up a structure like this

41
00:01:52,210 --> 00:01:56,380
and working with four tables as we did it with SQL,

42
00:01:56,380 --> 00:02:00,350
when working with no SQL, in this case with MongoDB,

43
00:02:00,350 --> 00:02:02,890
we could set up a structure like this,

44
00:02:02,890 --> 00:02:06,450
where we work with free collections to the end.

45
00:02:06,450 --> 00:02:07,283
Now, of course,

46
00:02:07,283 --> 00:02:10,889
there will always be more than one possible implementation,

47
00:02:10,889 --> 00:02:12,570
but let me explain why I think

48
00:02:12,570 --> 00:02:16,350
that this implementation here might be a good idea.

49
00:02:16,350 --> 00:02:18,680
I'm working with three collections here.

50
00:02:18,680 --> 00:02:22,860
And my main idea is that I store all the data

51
00:02:22,860 --> 00:02:26,390
for my restaurants in the restaurants collection.

52
00:02:26,390 --> 00:02:29,840
I'll come back to the types collection in a second.

53
00:02:29,840 --> 00:02:31,050
Now to be precise,

54
00:02:31,050 --> 00:02:33,860
I have to name for my restaurant stored

55
00:02:33,860 --> 00:02:35,110
in the restaurant's collection,

56
00:02:35,110 --> 00:02:38,800
and then also all the address details.

57
00:02:38,800 --> 00:02:39,633
And that's of course,

58
00:02:39,633 --> 00:02:41,300
a difference to the SQL world

59
00:02:41,300 --> 00:02:44,683
where we had a separate addresses database table.

60
00:02:45,670 --> 00:02:49,380
Now I do store the address as a nested object

61
00:02:49,380 --> 00:02:52,550
in my restaurants documents because,

62
00:02:52,550 --> 00:02:54,810
it's tightly, coupled to my restaurants,

63
00:02:54,810 --> 00:02:57,760
chances are high that in my application,

64
00:02:57,760 --> 00:02:59,800
when I fetch a list of restaurants,

65
00:02:59,800 --> 00:03:03,000
I also need the addresses, and I don't want

66
00:03:03,000 --> 00:03:06,250
to get that from a extra collection from before,

67
00:03:06,250 --> 00:03:07,690
and in addition,

68
00:03:07,690 --> 00:03:11,210
the address of a restaurant is not going to change a lot.

69
00:03:11,210 --> 00:03:15,340
and not a lot of addresses will have the same address.

70
00:03:15,340 --> 00:03:18,700
It can occur if they're in some kind of shopping mall,

71
00:03:18,700 --> 00:03:22,520
but typically every restaurant will have its own address.

72
00:03:22,520 --> 00:03:26,090
So therefore having the address data as a nested object

73
00:03:26,090 --> 00:03:27,980
will be pretty good.

74
00:03:27,980 --> 00:03:29,760
It will help be with querying,

75
00:03:29,760 --> 00:03:31,550
with fetching the data.

76
00:03:31,550 --> 00:03:34,270
And if I need to change an address,

77
00:03:34,270 --> 00:03:38,580
I probably only need to do it for one or a few restaurants.

78
00:03:38,580 --> 00:03:42,010
So I don't need to touch a lot of restaurant documents

79
00:03:42,010 --> 00:03:42,843
to do that.

80
00:03:44,580 --> 00:03:47,140
Now for it to type it's a bit more tricky.

81
00:03:47,140 --> 00:03:50,980
Here I'm also a fan of storing the type directly

82
00:03:50,980 --> 00:03:54,483
for my restaurant, since I'll typically query that together.

83
00:03:55,550 --> 00:03:58,460
And that generally would also be good.

84
00:03:58,460 --> 00:04:02,010
The type is probably not going to change a lot,

85
00:04:02,010 --> 00:04:04,520
probably never for a restaurant.

86
00:04:04,520 --> 00:04:08,490
So I don't need to touch this a lot, but of course,

87
00:04:08,490 --> 00:04:12,780
I don't want to have one restaurant that's labeled American

88
00:04:12,780 --> 00:04:17,070
and another restaurant that's labeled USA Food.

89
00:04:17,070 --> 00:04:19,600
I don't think anyone would use this term,

90
00:04:19,600 --> 00:04:21,329
but you get the idea.

91
00:04:21,329 --> 00:04:25,220
I don't want to have different type labels,

92
00:04:25,220 --> 00:04:28,360
if we're in the end talking about the same type,

93
00:04:28,360 --> 00:04:30,950
but we just wrote them differently.

94
00:04:30,950 --> 00:04:32,460
That's why we might want

95
00:04:32,460 --> 00:04:35,930
to add a third extra types collection,

96
00:04:35,930 --> 00:04:38,640
which stores all the predefined types,

97
00:04:38,640 --> 00:04:41,970
which we then could use in a form that we present

98
00:04:41,970 --> 00:04:44,200
to a user, inside of a dropdown

99
00:04:44,200 --> 00:04:46,140
to choose a type from,

100
00:04:46,140 --> 00:04:48,610
so that this is not a free text field,

101
00:04:48,610 --> 00:04:52,120
but instead a list of predefined types.

102
00:04:52,120 --> 00:04:54,450
But then once we store our restaurant,

103
00:04:54,450 --> 00:04:56,990
we store the idea of the type

104
00:04:56,990 --> 00:04:59,710
and the types collection for completeness sake.

105
00:04:59,710 --> 00:05:02,870
But we also just copied the name of the type directly

106
00:05:02,870 --> 00:05:04,683
into the restaurant's collection.

107
00:05:05,530 --> 00:05:08,290
Therefore we'll have some duplicate data

108
00:05:08,290 --> 00:05:11,910
because the type name, the human readable name

109
00:05:11,910 --> 00:05:14,790
will be part of both the restaurant's documents,

110
00:05:14,790 --> 00:05:18,670
as well as off the documents in the types collection.

111
00:05:18,670 --> 00:05:22,530
But since those types will probably never change,

112
00:05:22,530 --> 00:05:26,090
this kind of duplicate data is no problem.

113
00:05:26,090 --> 00:05:28,000
If we would change them a lot,

114
00:05:28,000 --> 00:05:30,260
we would have to update the type names

115
00:05:30,260 --> 00:05:33,370
in two different collections and in a lot of documents,

116
00:05:33,370 --> 00:05:34,900
which would be a nightmare.

117
00:05:34,900 --> 00:05:38,420
But since German will always be named German,

118
00:05:38,420 --> 00:05:41,600
as a restaurant type, we will never have to change it

119
00:05:41,600 --> 00:05:43,660
in any places.

120
00:05:43,660 --> 00:05:45,920
And therefore having this kind of duplicate data

121
00:05:45,920 --> 00:05:47,640
is a good idea.

122
00:05:47,640 --> 00:05:51,010
You could also work without that separate types collection,

123
00:05:51,010 --> 00:05:52,580
but for the reasons mentioned,

124
00:05:52,580 --> 00:05:56,240
to ensure that you don't enter arbitrary values,

125
00:05:56,240 --> 00:05:58,743
we could have that separate collection year.

126
00:06:00,650 --> 00:06:05,080
And then, we also want to have some reviews.

127
00:06:05,080 --> 00:06:09,610
Now we could store reviews as a nested array

128
00:06:09,610 --> 00:06:12,440
for every restaurant document.

129
00:06:12,440 --> 00:06:16,040
Every restaurant document could have a reviews field,

130
00:06:16,040 --> 00:06:20,150
which is an array off review objects,

131
00:06:20,150 --> 00:06:24,300
but one restaurant can of course have hundreds

132
00:06:24,300 --> 00:06:26,180
or thousands of reviews.

133
00:06:26,180 --> 00:06:30,160
And with MongoDB or no SQL in general,

134
00:06:30,160 --> 00:06:32,850
you want to avoid having nested data

135
00:06:32,850 --> 00:06:35,460
that can grow infinitely,

136
00:06:35,460 --> 00:06:37,810
also because there is a size limit

137
00:06:37,810 --> 00:06:40,800
for the maximum size a document may have.

138
00:06:40,800 --> 00:06:42,930
And you might go beyond that limit

139
00:06:42,930 --> 00:06:45,930
if you have such infinite lists.

140
00:06:45,930 --> 00:06:47,170
So you don't want to do that.

141
00:06:47,170 --> 00:06:50,590
If you have a possibly infinite list of data,

142
00:06:50,590 --> 00:06:53,250
you want to put that into a separate collection,

143
00:06:53,250 --> 00:06:56,110
not into some nested field in a document

144
00:06:56,110 --> 00:06:57,770
in another collection.

145
00:06:57,770 --> 00:07:00,600
That's why we should have a separate reviews collection

146
00:07:00,600 --> 00:07:02,580
where we store all the reviews.

147
00:07:02,580 --> 00:07:03,950
And then there, of course,

148
00:07:03,950 --> 00:07:07,540
we point at the restaurant to which a review belongs

149
00:07:07,540 --> 00:07:09,980
with the restaurant ID.

150
00:07:09,980 --> 00:07:13,120
We could even store some extra restaurant data

151
00:07:13,120 --> 00:07:15,090
like the restaurant name here,

152
00:07:15,090 --> 00:07:17,560
side-by-side with the restaurant ID

153
00:07:17,560 --> 00:07:19,400
in our review documents.

154
00:07:19,400 --> 00:07:22,230
So that when we fetch a list of reviews,

155
00:07:22,230 --> 00:07:25,660
we also have that restaurant name at hand,

156
00:07:25,660 --> 00:07:27,630
that depends on which kind of queries

157
00:07:27,630 --> 00:07:29,030
you will be running later,

158
00:07:29,030 --> 00:07:31,430
and if you need that restaurant name together

159
00:07:31,430 --> 00:07:33,620
with your reviews a lot or not,

160
00:07:33,620 --> 00:07:35,280
at chances are that you do,

161
00:07:35,280 --> 00:07:38,060
and then duplicating that restaurant name

162
00:07:38,060 --> 00:07:41,910
into the review documents might be a good idea,

163
00:07:41,910 --> 00:07:44,860
also because the restaurant name is also not going

164
00:07:44,860 --> 00:07:45,930
to change a lot,

165
00:07:45,930 --> 00:07:49,690
So you won't need to update it in dozens or hundreds

166
00:07:49,690 --> 00:07:51,360
of reviews all the time.

167
00:07:51,360 --> 00:07:53,330
For fast changing data,

168
00:07:53,330 --> 00:07:55,190
you want to avoid duplication

169
00:07:55,190 --> 00:07:57,830
for data that barely ever changes.

170
00:07:57,830 --> 00:08:01,360
You can absolutely duplicated it to make your queries

171
00:08:01,360 --> 00:08:03,863
for fetching the data more efficient.

172
00:08:04,840 --> 00:08:07,610
And then, that's how I store my data here.

173
00:08:07,610 --> 00:08:09,510
And I think I will go for the extra

174
00:08:09,510 --> 00:08:11,670
restaurant names stored in addition

175
00:08:11,670 --> 00:08:14,210
to the restaurant ID in my reviews.

176
00:08:14,210 --> 00:08:16,930
And therefore this will be the final structure

177
00:08:16,930 --> 00:08:19,900
I will implement over the next lectures.

178
00:08:19,900 --> 00:08:24,870
And of course as always, feel free to try storing that data,

179
00:08:24,870 --> 00:08:26,760
creating that data on your own,

180
00:08:26,760 --> 00:08:28,750
work with some dummy data

181
00:08:28,750 --> 00:08:30,810
and these free collections,

182
00:08:30,810 --> 00:08:34,860
maybe clear the existing documents you have

183
00:08:34,860 --> 00:08:36,850
in your restaurants collection already

184
00:08:36,850 --> 00:08:38,049
from the last lectures.

185
00:08:38,049 --> 00:08:40,210
And then try building this on your own.

186
00:08:40,210 --> 00:08:41,419
Over the next lectures,

187
00:08:41,419 --> 00:08:43,200
we're going to set up the structure

188
00:08:43,200 --> 00:08:45,073
and store some dummy data together.

