Would you like to inspect the original subtitles? These are the user uploaded subtitles that are being translated:
1
00:00:01,330 --> 00:00:04,200
Welcome back after a long lecture
2
00:00:04,200 --> 00:00:06,470
where we searched for tour documents
3
00:00:06,470 --> 00:00:08,170
within a certain distance
4
00:00:08,170 --> 00:00:11,930
from a certain point using geospatial queries.
5
00:00:11,930 --> 00:00:15,840
Now in this lecture, let's use geospatial aggregation
6
00:00:15,840 --> 00:00:17,580
in order to calculate distances
7
00:00:17,580 --> 00:00:20,073
to all the tours from a certain point.
8
00:00:21,970 --> 00:00:24,320
So just like before let's actually start
9
00:00:24,320 --> 00:00:26,510
by defining the route so that we know
10
00:00:26,510 --> 00:00:28,610
which data we're going to be working with.
11
00:00:31,750 --> 00:00:36,150
So router.route;
12
00:00:36,150 --> 00:00:40,760
at this time I'm gonna call it simply distances,
13
00:00:40,760 --> 00:00:43,130
and then the data that we need
14
00:00:43,130 --> 00:00:45,050
is the latitude and the longitude
15
00:00:45,050 --> 00:00:47,193
of the point where the user currently is,
16
00:00:48,090 --> 00:00:51,103
so in our previous example that was LA,
17
00:00:52,840 --> 00:00:54,310
and then let's also allow the user
18
00:00:54,310 --> 00:00:57,273
again to specify the unit.
19
00:00:59,370 --> 00:01:02,150
Then here, the route handler function.
20
00:01:02,150 --> 00:01:03,060
Now this time here,
21
00:01:03,060 --> 00:01:05,850
we do not need the distance parameter,
22
00:01:05,850 --> 00:01:07,250
as we had it right here,
23
00:01:07,250 --> 00:01:10,600
because we're not gonna be searching for a certain radius.
24
00:01:10,600 --> 00:01:12,620
We're really gonna calculate the distance
25
00:01:12,620 --> 00:01:14,880
from a certain point to all the tours
26
00:01:14,880 --> 00:01:16,683
that we have in our collection.
27
00:01:17,530 --> 00:01:20,483
So the handler is at tourController,
28
00:01:21,880 --> 00:01:24,077
and it's gonna be called getDistances.
29
00:01:28,710 --> 00:01:32,033
We don't have that yet, and so let's create it.
30
00:01:37,610 --> 00:01:42,210
CatchAsync, and then of course
31
00:01:42,210 --> 00:01:45,170
mark the function as async as well
32
00:01:45,170 --> 00:01:47,620
because we already know that we're gonna use
33
00:01:47,620 --> 00:01:50,210
the aggregation pipeline, and so by the time
34
00:01:50,210 --> 00:01:52,393
we're gonna be using a wait.
35
00:01:57,771 --> 00:02:02,070
The beginning of this function is actually quite similar
36
00:02:02,070 --> 00:02:05,470
to the getToursWithin one, and so let's go ahead
37
00:02:05,470 --> 00:02:07,223
and just copy all of this code.
38
00:02:08,729 --> 00:02:11,830
We have some similar units, then we also need to get
39
00:02:11,830 --> 00:02:13,450
the latitude and longitude,
40
00:02:13,450 --> 00:02:15,520
and we also need to create this error
41
00:02:15,520 --> 00:02:18,583
in case there is no latitude or no longitude.
42
00:02:21,980 --> 00:02:23,890
This one here does not apply,
43
00:02:23,890 --> 00:02:25,833
and also we don't have the distance.
44
00:02:28,526 --> 00:02:30,713
So let's now do the actual calculation.
45
00:02:31,800 --> 00:02:34,660
Just like before in order to do calculations
46
00:02:34,660 --> 00:02:37,730
we always use the aggregation pipeline.
47
00:02:37,730 --> 00:02:40,513
And remember, that is called on the model itself.
48
00:02:41,520 --> 00:02:43,923
So Tour.aggregate.
49
00:02:45,800 --> 00:02:48,830
Then let's await that, and save it
50
00:02:48,830 --> 00:02:50,723
into the distances variable.
51
00:02:55,349 --> 00:02:58,020
So then here, remember, we passed in an array
52
00:02:58,020 --> 00:03:00,803
with all the stages of the aggregation pipeline
53
00:03:00,803 --> 00:03:02,700
that we want to define.
54
00:03:02,700 --> 00:03:04,660
Now for geospatial aggregation,
55
00:03:04,660 --> 00:03:07,550
there's actually only one single stage,
56
00:03:07,550 --> 00:03:09,967
and that's called geoNear, so this one.
57
00:03:16,380 --> 00:03:18,518
Again, this is the only geospatial
58
00:03:18,518 --> 00:03:21,780
aggregation pipeline stage that actually exists.
59
00:03:21,780 --> 00:03:26,530
This one always needs to be the first one in the pipeline.
60
00:03:26,530 --> 00:03:28,840
So keep that in mind that geoNear
61
00:03:28,840 --> 00:03:31,173
always needs to be the first stage.
62
00:03:32,620 --> 00:03:35,700
Something else that's also very important to note
63
00:03:35,700 --> 00:03:38,370
about geoNear is that it requires
64
00:03:38,370 --> 00:03:40,430
that at least one of our fields
65
00:03:40,430 --> 00:03:42,713
contains a geospatial index.
66
00:03:43,930 --> 00:03:46,440
Actually we already did that before,
67
00:03:46,440 --> 00:03:48,965
so let's again take a look.
68
00:03:48,965 --> 00:03:51,290
Our start location already has
69
00:03:51,290 --> 00:03:54,895
this 2dsphere geospatial index on it.
70
00:03:54,895 --> 00:03:57,290
Since we're using this startLocation
71
00:03:57,290 --> 00:03:59,390
in order to calculate the distances,
72
00:03:59,390 --> 00:04:01,593
well, that's then perfect.
73
00:04:03,050 --> 00:04:06,138
If there's only one field with a geospatial index
74
00:04:06,138 --> 00:04:10,120
then this geoNear stage here will automatically use
75
00:04:10,120 --> 00:04:13,490
that index in order to perform the calculation.
76
00:04:13,490 --> 00:04:16,570
But if you have multiple fields with geospatial indexes
77
00:04:16,570 --> 00:04:18,880
then you need to use the keys parameter
78
00:04:18,880 --> 00:04:20,440
in order to define the field
79
00:04:20,440 --> 00:04:22,623
that you want to use for calculations.
80
00:04:24,429 --> 00:04:26,120
So keep that in mind, but again,
81
00:04:26,120 --> 00:04:27,960
in this case we only have one field,
82
00:04:27,960 --> 00:04:30,850
and so automatically that startLocation field
83
00:04:30,850 --> 00:04:33,740
is going to be used for doing these calculations.
84
00:04:33,740 --> 00:04:37,230
So, what do we need to pass into geoNear?
85
00:04:37,230 --> 00:04:41,396
Well, first we need to specify the near property,
86
00:04:41,396 --> 00:04:45,800
and near is the point from which to calculate the distances.
87
00:04:45,800 --> 00:04:49,030
So all the distances will be calculated from this point
88
00:04:49,030 --> 00:04:52,410
that we define here, and then all the start locations.
89
00:04:52,410 --> 00:04:54,804
So this near point here is of course
90
00:04:54,804 --> 00:04:57,602
the point that we pass into this function
91
00:04:57,602 --> 00:04:59,743
with this latitude and longitude.
92
00:05:01,496 --> 00:05:05,773
Now we need to specify this point here as geojson,
93
00:05:06,890 --> 00:05:09,180
so that's just like we did it before,
94
00:05:09,180 --> 00:05:12,153
where we need to specify the type as Point,
95
00:05:14,517 --> 00:05:17,647
and then specify the coordinates property.
96
00:05:20,320 --> 00:05:23,423
And as always the first coordinate here is the longitude,
97
00:05:25,640 --> 00:05:28,530
and then the second one, the latitude.
98
00:05:28,530 --> 00:05:31,520
And let's multiply both of them by one,
99
00:05:31,520 --> 00:05:34,053
simply to convert it to numbers.
100
00:05:36,240 --> 00:05:40,060
So this is the first mandatory field, near,
101
00:05:40,060 --> 00:05:43,563
and the second one is the distance field property.
102
00:05:46,160 --> 00:05:48,870
So, distanceField, and so this is the name
103
00:05:48,870 --> 00:05:51,090
of the field that will be created
104
00:05:51,090 --> 00:05:54,270
and where all the calculated distances will be stored.
105
00:05:54,270 --> 00:05:57,653
So let's simply call this one distance.
106
00:05:59,710 --> 00:06:01,660
Actually, that's it.
107
00:06:01,660 --> 00:06:03,770
That's all the fields that are mandatory
108
00:06:03,770 --> 00:06:06,180
in this geoNear stage.
109
00:06:06,180 --> 00:06:08,560
And of course, we can add other stages here,
110
00:06:08,560 --> 00:06:10,740
and we're actually going to do that a bit later,
111
00:06:10,740 --> 00:06:12,570
but for now all I want to do
112
00:06:12,570 --> 00:06:15,573
is to really see the results of this working.
113
00:06:17,670 --> 00:06:22,410
Let's again copy this a result here,
114
00:06:22,410 --> 00:06:27,410
thus sending these results, and here,
115
00:06:27,600 --> 00:06:29,503
let's then send the distances,
116
00:06:30,810 --> 00:06:32,410
and also this one we don't need.
117
00:06:35,524 --> 00:06:37,860
So, we're ready to start.
118
00:06:37,860 --> 00:06:40,680
Keep in mind that at this point we didn't use the unit,
119
00:06:40,680 --> 00:06:42,370
but don't worry about that.
120
00:06:42,370 --> 00:06:44,580
We're gonna do that in a second,
121
00:06:44,580 --> 00:06:47,723
but again, first I really want to see this working.
122
00:06:50,320 --> 00:06:52,623
Remember that the route is now distances,
123
00:06:55,180 --> 00:06:57,190
so let's just copy this one here.
124
00:06:57,190 --> 00:06:58,763
Actually, I will save it also,
125
00:06:59,790 --> 00:07:01,223
so into the tours.
126
00:07:03,860 --> 00:07:07,710
Let's say get tours within radius.
127
00:07:16,540 --> 00:07:21,540
This here is called distances,
128
00:07:22,000 --> 00:07:26,290
and we do not have this and also not this.
129
00:07:26,290 --> 00:07:29,523
So just the coordinates, and then again the unit.
130
00:07:31,040 --> 00:07:35,740
Let's take a look, and we will now get this error.
131
00:07:35,740 --> 00:07:38,100
Remember how we said that geoNear
132
00:07:38,100 --> 00:07:41,750
always needs to be the first stage in a pipeline,
133
00:07:41,750 --> 00:07:43,870
but if you now take a look at the code
134
00:07:43,870 --> 00:07:48,510
you might think that actually our geoNear stage
135
00:07:48,510 --> 00:07:51,690
is currently the first stage of our pipeline.
136
00:07:51,690 --> 00:07:55,290
Because right here, it actually looks like it is, right?
137
00:07:55,290 --> 00:07:58,530
There's nothing before this, and so why do we get this error
138
00:07:58,530 --> 00:08:02,134
that geoNear is not the first stage in the pipeline?
139
00:08:02,134 --> 00:08:06,010
Actually it took me a bit of time to figure this out
140
00:08:06,010 --> 00:08:08,730
because this has something to do with a piece of code
141
00:08:08,730 --> 00:08:10,623
that we wrote a long time ago.
142
00:08:12,050 --> 00:08:14,240
That's here in the tour model,
143
00:08:14,240 --> 00:08:16,623
and if we go down here, I think.
144
00:08:19,480 --> 00:08:22,440
Right here, we have this aggregation middleware,
145
00:08:22,440 --> 00:08:26,220
and remember that what this did is to actually always add
146
00:08:26,220 --> 00:08:29,840
this match stage here before all the other stages,
147
00:08:29,840 --> 00:08:32,049
and actually we have this console.log here
148
00:08:32,049 --> 00:08:34,700
and so indeed you can actually see
149
00:08:34,700 --> 00:08:36,592
the entire pipeline down here.
150
00:08:37,789 --> 00:08:40,059
And so you see that we first have the match,
151
00:08:40,059 --> 00:08:42,130
and then the geoNear phase here,
152
00:08:42,130 --> 00:08:45,230
actually only as the second stage.
153
00:08:45,230 --> 00:08:48,670
So it actually makes sense that we get that error.
154
00:08:48,670 --> 00:08:52,120
Now we could go ahead and change this middleware here
155
00:08:52,120 --> 00:08:55,630
and say that if geoNear is the first operator
156
00:08:55,630 --> 00:08:59,873
in the pipeline, then simply do not do this here.
157
00:08:59,873 --> 00:09:03,530
But that's a bit too much work for this use case,
158
00:09:03,530 --> 00:09:06,853
so all I'm gonna do is to get rid of this middleware.
159
00:09:08,448 --> 00:09:11,833
So give this a save, and now let's try it again.
160
00:09:13,929 --> 00:09:16,420
Now we get our tours, and now it should have
161
00:09:16,420 --> 00:09:18,633
that distance field on them.
162
00:09:19,520 --> 00:09:24,230
So let's search for that, and indeed here it goes.
163
00:09:24,230 --> 00:09:27,588
So distance, and then this huge number here.
164
00:09:27,588 --> 00:09:29,740
It is this big number,
165
00:09:29,740 --> 00:09:32,490
because actually it's calculated in meters,
166
00:09:32,490 --> 00:09:35,270
so this result comes in meters,
167
00:09:35,270 --> 00:09:38,683
so let's first of all convert this one to kilometers.
168
00:09:39,560 --> 00:09:42,630
Later on we will then also convert it to miles,
169
00:09:42,630 --> 00:09:46,120
because remember we specified the unit to miles,
170
00:09:46,120 --> 00:09:47,860
but for now the easiest solution
171
00:09:47,860 --> 00:09:49,960
is to actually convert it to kilometers,
172
00:09:49,960 --> 00:09:51,640
because all we have to do for that
173
00:09:51,640 --> 00:09:54,920
is to just divide it by 1000.
174
00:09:54,920 --> 00:09:56,250
And then also what I want to do
175
00:09:56,250 --> 00:09:58,950
is to only really get the distances,
176
00:09:58,950 --> 00:10:00,530
and the name of the tours.
177
00:10:00,530 --> 00:10:04,170
So get rid of all the other clutter that we have here
178
00:10:04,170 --> 00:10:07,133
and really only focus on the distances themselves.
179
00:10:08,610 --> 00:10:11,160
For that, as you might remember,
180
00:10:11,160 --> 00:10:14,350
we can use the project stage.
181
00:10:14,350 --> 00:10:17,163
So let's add that here as the second stage.
182
00:10:20,160 --> 00:10:24,470
So project, and then basically the names
183
00:10:24,470 --> 00:10:26,373
of the fields that we want to keep.
184
00:10:27,230 --> 00:10:31,003
So that's the distance, and so we set that one to one,
185
00:10:32,100 --> 00:10:35,757
saying that we want to keep it, and then also the name
186
00:10:35,757 --> 00:10:39,653
so that we actually know what tour we're talking about.
187
00:10:40,990 --> 00:10:43,800
With that we get rid of all the other data,
188
00:10:43,800 --> 00:10:47,220
and now let's basically divide the distance by 1000
189
00:10:47,220 --> 00:10:50,320
in order to convert these meters to kilometers.
190
00:10:50,320 --> 00:10:52,590
Actually, it's very easy to do that,
191
00:10:52,590 --> 00:10:56,249
because in a geoNear stage we can actually specify
192
00:10:56,249 --> 00:10:59,543
the distance multiplier property.
193
00:11:00,410 --> 00:11:05,410
So distanceMultiplier, and so here we can specify a number
194
00:11:07,470 --> 00:11:10,790
which is then going to be multiplied with all the distances.
195
00:11:10,790 --> 00:11:15,790
Here we specify 0.001, and so that is exactly the same
196
00:11:16,080 --> 00:11:17,763
as dividing by 1000.
197
00:11:19,860 --> 00:11:21,763
So let's test our result here now.
198
00:11:23,210 --> 00:11:25,760
And that calculation apparently takes some time,
199
00:11:25,760 --> 00:11:26,983
but now here we go.
200
00:11:27,820 --> 00:11:32,050
So now you get this nice result here in kilometers.
201
00:11:32,050 --> 00:11:35,200
As you see the Sports Lover is the closest tour
202
00:11:35,200 --> 00:11:37,920
to the location in Los Angeles that we marked.
203
00:11:37,920 --> 00:11:40,220
So it's only 64 kilometers away,
204
00:11:40,220 --> 00:11:42,430
which should be something like 40 miles.
205
00:11:42,430 --> 00:11:45,380
But again, we're going to do that conversion in a second.
206
00:11:45,380 --> 00:11:48,487
For now, I just want to go back to that map and compass
207
00:11:48,487 --> 00:11:50,863
and see if this actually makes sense.
208
00:11:53,530 --> 00:11:56,800
So we're still here,
209
00:11:56,800 --> 00:11:59,513
and we still have our start locations map.
210
00:12:01,100 --> 00:12:01,933
Now the problem here
211
00:12:01,933 --> 00:12:04,980
is that we actually cannot really click
212
00:12:04,980 --> 00:12:07,433
on any of these points and see what they are.
213
00:12:08,960 --> 00:12:11,660
But let's just draw a quick circle here again
214
00:12:12,670 --> 00:12:15,000
just to see which are the closest tours,
215
00:12:15,000 --> 00:12:17,770
and if they match the ones in our output.
216
00:12:17,770 --> 00:12:19,753
So it's kind of here, I believe,
217
00:12:21,300 --> 00:12:24,303
and so let's include these five tours here.
218
00:12:27,070 --> 00:12:31,400
So their names are The Park Camper, Snow Adventurer,
219
00:12:31,400 --> 00:12:34,783
Wine Taster, Sports Lover and Star Gazer,
220
00:12:35,640 --> 00:12:37,893
and so now when we come here,
221
00:12:39,450 --> 00:12:42,150
these ones are actually the first five ones.
222
00:12:42,150 --> 00:12:43,970
Sports Lover, Park Camper, Wine Taster,
223
00:12:43,970 --> 00:12:46,700
Star Gazer and Snow Adventurer.
224
00:12:46,700 --> 00:12:49,490
So that one that's really close is the Sports Lover,
225
00:12:49,490 --> 00:12:51,310
and then the next one is the Park Camper
226
00:12:51,310 --> 00:12:52,763
and the Wine Taster.
227
00:12:58,079 --> 00:13:00,490
This one here is going to be the Park Camper,
228
00:13:00,490 --> 00:13:02,870
which I believe starts in Las Vegas,
229
00:13:02,870 --> 00:13:04,300
so that makes sense,
230
00:13:04,300 --> 00:13:06,473
and then a third one is here,
231
00:13:06,473 --> 00:13:09,780
The Wine Taster close to San Francisco.
232
00:13:09,780 --> 00:13:13,160
So that distance of 800 kilometers I think,
233
00:13:13,160 --> 00:13:14,113
or what was that?
234
00:13:15,290 --> 00:13:19,060
Yeah, 600 kilometers, that actually makes kind of sense.
235
00:13:19,060 --> 00:13:21,593
So, something close to 400 miles here.
236
00:13:22,910 --> 00:13:25,070
And speaking of miles, let's actually do
237
00:13:25,070 --> 00:13:26,513
that conversion right now.
238
00:13:28,030 --> 00:13:31,570
Let's do something similar to what we did before,
239
00:13:31,570 --> 00:13:33,523
so testing for the unit.
240
00:13:34,570 --> 00:13:36,943
Let's create a multiplier variable,
241
00:13:39,320 --> 00:13:41,713
again a ternary operator here,
242
00:13:45,030 --> 00:13:49,070
so if it's miles then what should our multiplier be?
243
00:13:49,070 --> 00:13:50,630
Well, let's actually very simply
244
00:13:50,630 --> 00:13:53,703
Google what one meter is in miles.
245
00:13:58,320 --> 00:14:03,250
One meter to miles, and Google usually gives us
246
00:14:03,250 --> 00:14:08,210
a pretty nice response, and so indeed, that it is.
247
00:14:08,210 --> 00:14:11,750
So if this is one meter, then all we need to do
248
00:14:11,750 --> 00:14:14,660
is to really multiply our result in meters
249
00:14:14,660 --> 00:14:15,863
with this number.
250
00:14:16,800 --> 00:14:20,340
So let's copy it here, and go back,
251
00:14:20,340 --> 00:14:22,500
and so this should be our multiplier
252
00:14:22,500 --> 00:14:26,690
in case the unit is meters, or actually in case it's miles.
253
00:14:26,690 --> 00:14:29,030
And in case it's meters, well then
254
00:14:29,030 --> 00:14:32,843
it's that 0.001 that we used before.
255
00:14:34,670 --> 00:14:36,060
We don't want it in meters,
256
00:14:36,060 --> 00:14:39,000
because that's not really a readable unit.
257
00:14:39,000 --> 00:14:40,823
Instead we want it in kilometers.
258
00:14:42,910 --> 00:14:46,563
So now we can go ahead and use out multiplier variable here,
259
00:14:48,060 --> 00:14:51,363
give it a save, and let's try it out.
260
00:14:54,450 --> 00:14:57,400
So take a look at what we have here in kilometers,
261
00:14:57,400 --> 00:15:00,650
so from the previous result, which is 64.
262
00:15:00,650 --> 00:15:05,650
That should approximately be 40 miles, so let's send that,
263
00:15:06,560 --> 00:15:08,720
and that was pretty close.
264
00:15:08,720 --> 00:15:11,370
So 40.2 miles indeed.
265
00:15:11,370 --> 00:15:13,450
And so that's our closest tours,
266
00:15:13,450 --> 00:15:18,010
and the most farthest away is the City Wonderer,
267
00:15:18,010 --> 00:15:20,630
which I think starts in New York or something,
268
00:15:20,630 --> 00:15:24,843
and so that is more than 2400 miles away from L.A.
269
00:15:27,630 --> 00:15:30,770
If we then set it here to kilometers,
270
00:15:30,770 --> 00:15:33,490
then it should be back to getting the value
271
00:15:33,490 --> 00:15:34,583
that we had before.
272
00:15:36,960 --> 00:15:38,410
Let's put it back to miles
273
00:15:38,410 --> 00:15:41,370
because I know that most people watching this course
274
00:15:41,370 --> 00:15:45,093
are from the U.S., and so over there they use miles
275
00:15:45,093 --> 00:15:47,320
instead of kilometers.
276
00:15:47,320 --> 00:15:50,710
So let's save this here as well to our collection
277
00:15:52,300 --> 00:15:57,210
get distances to tours from point.
278
00:16:01,940 --> 00:16:04,430
So that's it, that wraps up this lecture,
279
00:16:04,430 --> 00:16:08,160
and that's all I had to show you about geospatial data.
280
00:16:08,160 --> 00:16:10,730
So this video and the last one should have given you
281
00:16:10,730 --> 00:16:13,180
a very great overview of how to work
282
00:16:13,180 --> 00:16:16,260
with geospatial data in MongoDB.
283
00:16:16,260 --> 00:16:18,900
And as I said before there's a ton of possibilities
284
00:16:18,900 --> 00:16:21,647
of stuff that you can do in your own applications
285
00:16:21,647 --> 00:16:23,563
using this kind of data.
22579
Can't find what you're looking for?
Get subtitles in any language from opensubtitles.com, and translate them here.