There's plenty of reasons you might want to find all people or places within a certain distance of a zip code. You might want to locate all of your customers near a particular store to notify them of a sale or plot all known Covid-19 outbreaks in a particular area.
A typical document with an address might look something like this:
Before you can do a Geo lookup, you need to convert the zip code to a GeoJSON point (longitude and latitude). To find the coordinates for your zip codes, you're going to use the uszipcode python library.
Your updated document will look something like this:
It's worth noting the order of the coordinates, according to the GeoJSON format RFC this should be longitude then latitude.
You can check it has worked by checking the schema of your collection using MongoDB Compass. If you've created the GeoJSON point correctly, you should get a beautiful map with the location of your user's plotted on it.
To find all users within a certain distance of a zip code, first, we have to convert the target zip code into a longitude then latitude pair as well. Then you can use an aggregation pipeline to query MongoDB.
$geoWithin selects documents with geospatial data that exists entirely within a specified shape. While
$centerSphere defines a circle for a geospatial query that uses spherical geometry.
$centerSphere takes two arguments;
- the grid coordinates of the circle’s centre point, this is the longitude/latitude of the target zip code
- and the circle’s radius measured in radians
To convert distance to radians, you divide the distance by the radius of the sphere (e.g. the Earth), in the same units as the distance measurement. The radius of the Earth is approximately 3,963.2 miles or 6,378.1 kilometres.
What that means is, if you're using kilometres then you divide the number of kilometres you want to search within by the radius of the Earth in kilometres (6,378.1), if you're using miles, then you divide your distance by the radius of the Earth in miles (3,963.2).
If you wanted to find all users with 50 kilometres the value of the second argument would be
50 / 6378.1, if you wanted to search for all users within 200 miles it would be
200 / 3963.2, and so on.
|Distance||Radians (Miles)||Radians (Kilometres)|
|25||25 / 3963.2||25 / 6378.1|
|50||50 / 3963.2||50 / 6378.1|
|100||100 / 3963.2||100 / 6378.1|
Breaking that down what it means is that you're drawing a circle centred on your target zip code, with a radius of 25 miles. And then you're instructing MongoDB to find all documents where the coordinates specified in
address.location are within this circle.
In the Charts below the top map is showing all users, while the bottom is showing only those users within 100 miles of zip code 90210.
You can get started on MongoDB Atlas for free, or use the coupon code AARON200 for $200 💰💰💰 of Atlas credit.