Instructor: Welcome back.
So after some heavier theory lectures,
now, we're finally gonna start implementing our data model
and starting with the locations.
So in this video, you're gonna learn all about
geospatial data in MongoDB.
And this is really a topic
that I personally find really exciting.
Now, remember from the previous lecture
that our location data will actually be embedded
into the tours.
And so therefore, we're basically gonna declare
everything that is related to locations
in our tour model.
All right, so let's open that one up and right at the end,
let's start by adding the startLocation.
Okay, so we will have startLocation
and then also, locations in general.
Now, MongoDB supports geospatial data out of the box.
And geospatial data is basically data that describes
places on earth using longitude and latitude coordinates.
Okay, so we can describe simple points
or we can also describe more complex geometries
like lines or even polygons or even multi-polygons.
So really, everything is possible
with geospatial data in MongoDB.
Okay, so let's add our startLocation field here
and then let's actually implement this geospatial data.
And MongoDB uses a special data format called GeoJSON.
All right, so.
GeoJSON, in order to specify geospatial data.
And now, how does this actually work?
Well, this object that we specified here
is actually, this time, not for the schema type options
as we have it, for example, up here.
So this object here is for the schema type options.
Remember that?
But now, this object here is actually really
an embedded object.
And so inside this object,
we can specify a couple of properties.
All right, and in order for this object to be recognized
as geospatial JSON, we need the type
and the coordinates properties, all right.
So we need type and we need
coordinates, all right.
And so now, each of these fields here,
so basically, each of these sub-fields is then gonna get
its own schema type options.
All right, so basically here, it's a bit nested,
so we have one level deeper.
Okay, so we have the type schema type options
and then we also need schema type options for coordinates
and again, just like we have up here in these other fields
with the difference that these are now sub-fields.
So type needs the type of string,
all right,
and the default should be point.
So remember how I said that we can specify
multiple geometries in MongoDB?
And the default one is always point.
But again, we could also specify polygons or lines
or other geometries like that.
But in this case, for the startLocation,
it really should be point.
And so let's actually make that the only possible option
by specifying the enum,
so the enumeration property.
So remember, we can specify an array
of all the possible options that this field can take
and so in this case, we only want it to be point, all right.
So we did that somewhere up here.
Yeah, right here with the difficulty
where we said it can only be either medium or difficult.
Right, and so here, we're doing the same thing,
but only with one option, okay.
So we need to define the type, remember,
and also, an array of coordinates.
Okay, and so we do that by saying number,
but then in these curly brackets.
Okay, and so that basically means that we expect
an array of numbers
and this array, as the name says, is the coordinates
of the point with the longitude first
and only second, the latitude.
And so that's a bit counterintuitive
because usually it works the other way around.
But in GeoJSON, that's just how it works.
So if you were to go, for example, to Google Maps
in order to get your coordinates,
then you will see first the latitude and then the longitude.
Let's actually take a look at that.
So
open up Maps here.
Let's say New York.
Okay, and if we now click somewhere here,
say here, then we get the coordinates
first with the latitude and second, the longitude.
All right, and in case your not familiar with that,
let's just zoom out a little bit here,
so we can see the entire earth.
Wow, what's that?
Okay.
So the latitude is basically the horizontal position
measured in degrees starting from the equator,
so from here to up here.
So in the equator, it's zero degrees
and up here, in the North Pole, it's 90 degrees.
And then the longitude
is just the same thing, but vertically.
So it's the position starting from a meridian,
which passes somewhere here, okay.
And so the longitude is the vertical position
starting from here.
And so that's why this point here that we got,
somewhere here,
somewhere here in Manhattan, has a latitude of 40
and a longitude of -73.
All right.
But anyway, let's go back to our code here, of course,
because I also want to specify a property for the address.
So add another string and then also, a description
of this startLocation
and that again, as a string, all right.
And we're not gonna say that any of these fields
should be required because we want to be allowed
to leave the startLocation blank.
Okay, so again, in order to specify geospatial data
with MongoDB, we basically need to create a new object
such as we did here.
And that object then needs to have at least two field names.
So coordinates has this array of numbers
and then the type, which should be of type string
and should be either point or some other
of these other geometries that I just told you about before.
Okay, and we can then of course add some more fields
to this object such as we did here, all right.
Now, remember how in the last lecture we said
how we were gonna embed all the locations
into the tour documents?
But right now, the startLocation here is not really
a document itself.
It's really just an object
describing a certain point on earth.
But in order to really create new documents
and then embed them into another document,
we actually need to create an array, all right.
So it's actually very similar to what we already have here,
but it needs to be an array.
And so that's what we're gonna do with our locations.
So locations, and now, I'm creating an array.
And then in this array is where I'm gonna specify
the object such as I did it before in startLocation.
Okay, and you will see what this will look like
in a second in the Compass application.
Okay, and so now, it's actually quite the same as before.
So the type, remember, for geospatial data
needs to be string.
The default needs to be point.
And also, it cannot be anything but point, okay.
So point.
Again, we need the coordinates as an array of numbers
and also, for all of these other locations,
we still want to specify an address and a description.
So string and here, I also want to specify the date,
so as a number.
And this date will basically be the day of the tour
in which people will go to this location.
Now, if we wanted to make it simpler,
we could delete the startLocation all together
and then simply define the first location
as the startLocation and set it to day number zero.
All right, but I decided it's nice to also have
the startLocation as a separate field.
Okay, so this is how you create embedded documents.
Remember we always need to use this array, okay.
And so by specifying basically an array of objects,
this will then create brand new documents
inside of the parent document,
which is, in this case, the tour.
All right, now, in order to create some locations,
I'm actually going to import all our original data.
All right, so instead of creating new tours,
I will delete the ones we have
and then import the complete data.
So here, in dev-data,
remember that before we imported tours-simple.
Okay, so this kind of data here.
But we also have tours and this then actually has
the locations and the startLocation.
So I'm not sure where that startLocation is.
Ah, here it is.
So this is how we specify the startLocation
and you see that we have type set to point.
We have our array of coordinates.
And then of course, we have description and address.
And then down here, in the location, we have an array,
which then contains one object for each location.
And you see that actually each of them gets their own id.
And so these really are documents
and not just simple objects.
All right, so let's go here to our import-dev-data
and replace this here just with tours.
Give it a save and then remember, we need first to delete
and then to import.
So going to another console here.
We now want to run node,
dev-data and then import,
so actually, in the data folder, and then import.
And start by deleting and let's wait for it and indeed,
and now, import.
And here we go.
And let's check out Compass now.
Come to our tours.
And so indeed, you now see the startLocation here
as an object.
Okay, and when you open that up,
you see all the data that I just showed you before
in the JSON file.
Right, then here, also, the locations,
which you see as an array, so type array.
And then in there, we have all of these objects
and each object then also has its object id.
Okay, and so again, this is proof that we have now created,
embedded, or de-normalized datasets,
so datasets that have a really close relationship
with the tours data.
And so that's why we chose to really make it part
of the tours instead of creating its own collection
just for locations, right.
So we will actually use this a bit later in this section
once we start to create some special geospatial queries.
Okay, and with geospatial queries,
we can do really amazing stuff
like finding locations data closest to certain points
or find all locations inside a certain radius
or a certain sphere.
And really, the possibilities are absolutely endless, okay.
So we will just see some applications of this
by the end of this section
because for now, I really just wanted to show you
how we can create embedded datasets just as we just did.