AWS Database Blog

Introducing Geospatial query capabilities for Amazon DocumentDB (with MongoDB compatibility)

Amazon DocumentDB (with MongoDB compatibility) is a database service that is purpose-built for JSON data management at scale, fully managed and integrated with AWS, and enterprise-ready with high durability.

This post introduces you to the new geospatial query capabilities in Amazon DocumentDB, specifically the $nearSphere query operator and the $geoNear aggregation pipeline stage. For more information regarding geospatial query capabilities, see the Developer Guide.

With the added support for geospatial query capability in Amazon DocumentDB, you can answer questions like “Which three restaurants are nearest to my current location?” or “How many state capitals are within 100 kilometers of Boston, Massachusetts?”

Geometry

To perform geospatial queries, your documents must contain location information represented by GeoJSON type objects. In this first release of geospatial functionality, Amazon DocumentDB supports the GeoJSON Point type.

GeoJSON coordinates capture both longitude and latitude, representing positions on an earth-like sphere. The coordinates are presented in the format [longitude, latitude].

For example, you can create a collection of US state capitals named capitals, noting where each capital is located, using the following schema:

{
  state: "Albany",
  city: "New York",
  location: {
             type: "Point",
             coordinates: [-73.7562,42.6526]
            }
}

Indexing

After you have GeoJSON data in your documents, you need an index to support geospatial queries.

Building on the state capital example, you can create a geospatial index on the capitals collection as follows:

db.capitals.createIndex({location:"2dsphere"})

Create example data

The following commands create a geospatial index and insert state capitals for New England:

db.capitals.createIndex({location:"2dsphere"})
db.capitals.insert({state:"Maine",city:"Augusta",location:{type:"Point",coordinates:[-69.7795,44.3106]}});
db.capitals.insert({state:"New Hampshire",city:"Concord",location:{type:"Point",coordinates:[-71.5376,43.2081]}});
db.capitals.insert({state:"Vermont",city:"Montpelier",location:{type:"Point",coordinates:[-72.5754,44.2601]}});
db.capitals.insert({state:"Massachusetts",city:"Boston",location:{type:"Point",coordinates:[-71.0589,42.3601]}});
db.capitals.insert({state:"Rhode Island",city:"Providence",location:{type:"Point",coordinates:[-71.4128,41.8240]}});
db.capitals.insert({state:"Connecticut",city:"Hartford",location:{type:"Point",coordinates:[-72.6825,41.7642]}});

Now we can run some sample queries.

Query 1: List the state capitals sorted by distance from Boston, Massachusetts

The aggregation pipeline stage $geoNear calculates the distance in meters from a GeoJSON point, adding distanceMultiplier to the query returns the distance in kilometers.

The following query returns the state capitals and distance from Boston. The near attribute contains the GeoJSON point used for calculating the distance to the other state capitals, and the spherical attribute setting of true instructs the distance calculation to be done using spherical geometry (i.e. calculate distance assuming points are on the surface of an Earth-like sphere) :

db.capitals.aggregate( [
   { $geoNear: {
         near: { type: "Point", coordinates: [-71.0589,42.3601] },
         spherical: true,
         query: { city: {$ne:"Boston" }},
         distanceField: "DistanceKilometers",
         distanceMultiplier: 0.001}},
   { $project: {state:1,city:1,DistanceKilometers:1,_id:0}},
   { $sort: {DistanceKilometers:1}}
] )

The query returns the following output:

[
  {
    state: 'Rhode Island',
    city: 'Providence',
    DistanceKilometers: 66.4536844221711
  },
  {
    state: 'New Hampshire',
    city: 'Concord',
    DistanceKilometers: 102.17869999546963
  },
  {
    state: 'Connecticut',
    city: 'Hartford',
    DistanceKilometers: 149.68038982975406
  },
  {
    state: 'Maine',
    city: 'Augusta',
    DistanceKilometers: 240.56433987559393
  },
  {
    state: 'Vermont',
    city: 'Montpelier',
    DistanceKilometers: 244.57828100667356
  }
]

Query 2: List the state capitals within 100 kilometers of Boston

The find operator $nearSphere returns documents within a minimum $minDistance and maximum $maxDistance number of meters from a GeoJSON point.

For example, the following query returns the state capitals within 1 meter and 100 kilometers of Boston:

db.capitals.find(
   {
     location:
       { $nearSphere:
          {
            $geometry: { type: "Point",  coordinates: [-71.0589, 42.3601] },
            $minDistance: 1,
            $maxDistance: 100000
          }
       }
   },
   {state:1,city:1,_id:0}
)

We get the following response:

[
  { state: 'Rhode Island', city: 'Providence' },
  { state: 'New Hampshire', city: 'Concord' }
]

Summary

This post introduced geospatial query support in Amazon DocumentDB. For more information about geospatial query support in Amazon DocumentDB, see the Developer Guide.

If you have any questions or comments about this post, please use the comments section. If you have any features requests for Amazon DocumentDB, email us at documentdb-feature-request@amazon.com.


About the Author

Tim Callaghan is a Principal DocumentDB Specialist Solutions Architect at AWS. He enjoys working with customers looking to modernize existing data-driven applications and build new ones. Prior to joining AWS he has been both a consumer of Relational and NoSQL databases for over 30 years