Geospatial Queries

Geospatial Queries

MongoDB supports query operations on geospatial data. Geospatial data can help you store data that contains location and places to query them later to find for example some places in a zone or finding the nearest pharmacy or restaurant. There is a lot of stuff you can do with geospatial data we'll know more later

Geospatial GeoJSON objects

In MongoDB, you can store geospatial data as GeoJSON objects like the following:

Syntax of a GeoJSON Field

<field>: { type: <GeoJSON type> , coordinates: <coordinates> }

GeoJSON object type

MongoDB supports the GeoJSON object types listed below.

Type Syntax
Point { type: "Point", coordinates: [ 35, 7 ] }
LineString { type: "LineString", coordinates: [ [ 35, 7 ], [ 45, 15 ] ] }
Polygon with a Single Ring { type: "Polygon", coordinates: [ [ [ 0 , 0 ] , [ 35, 7 ], [ 45, 2 ] , [ 0 , 0 ] ] ]}
Polygons with Multiple Rings { type: "Polygon", coordinates: [
[ [ [ 0 , 0 ] , [ 35, 7 ], [ 45, 2 ] , [ 0 , 0 ] ] ],
[ [ [ 3 , 4 ] , [ 30, 6 ], [ 32, 2 ] , [ 3 , 4 ] ] ]
]}
MultiPoint { type: "MultiPoint",
coordinates: [
[ -73.9580, 40.8003 ],
[ -73.9498, 40.7968 ],
[ -73.9737, 40.7648 ],
[ -73.9814, 40.7681 ]
]}
More GeoJSON Objects

Example of a GeoJSON Field of type point

In this example i choosed some random longitude and latitude but feel free to use your own, or you can find this data on any kind of map (like google maps for example).

location: {
      type: "Point",
      coordinates: [-35.00, 10.958447]
}

To use some of the operators like $near on some GeoJSON types, MongoDB requires creating a 2dsphere index.

Creating a 2d sphere index

db.collection.createIndex( { <location field> : "2dsphere" } )

Querying and inserting Geospatial data

Inserting Geospatial data

db.coll.insert({
    name: "London",
    location: {
        type: "Point",
        coordinates: [-35.00, 10.958447]
    }
})

Creating a 2d sphere index

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

Geospatial operators and Querying Geospatial data

$near

Returns geospatial objects in proximity to a point. Requires a geospatial index. The 2dsphere and 2d indexes support $near.

Syntax
{
   <location field>: {
     $near: {
       $geometry: {
          type: "Point" ,
          coordinates: [ <longitude> , <latitude> ]
       },
       $maxDistance: <distance in meters>,
       $minDistance: <distance in meters>
     }
   }
}
Example of $near

Select all the cities that are at least 500 meters from and at most 4000 meters from the specified GeoJSON point, sorted from nearest to farthest:

db.coll.find(
    {
         location:
        { 
            $near :
            {
                $geometry: { type: "Point",  coordinates: [-34.991, 10.96] },
                $minDistance: 500,
                $maxDistance: 4000
            }
        }
    }
)

If specifying latitude and longitude coordinates, list the longitude first and then latitude:

  • Valid longitude values are between -180 and 180, both inclusive.
  • Valid latitude values are between -90 and 90, both inclusive.

$geoWithin

Selects geometries within a bounding GeoJSON geometry. The 2dsphere and 2d indexes support $geoWithin. $geoWithin Selects documents with geospatial data that exists entirely within a specified shape.

Syntax
{
   <location field>: {
      $geoWithin: {
         $geometry: {
            type: <"Polygon" or "MultiPolygon"> ,
            coordinates: [ <coordinates> ]
         }
      }
   }
}
Example of $geoWithin using Polygon

Select all the cities data that exist entirely within a GeoJSON Polygon:

db.coll.find(
   {
     location: {
       $geoWithin: {
          $geometry: {
             type : "Polygon" ,
             coordinates: [ [ [ -45, 20 ], [ 0, 20 ], [ 0, -20 ], [ -45, -20 ], [ -45, 20 ] ] ]
          }
       }
     }
   }
)

$geoIntersects

Selects geometries that intersect with a GeoJSON geometry where the intersection of the data and the specified object is non-empty.. The 2dsphere index supports $geoIntersects. For example a point inside a polygon.

Syntax
{
    <location field>: {
        $geoIntersects: {
            $geometry: {
            type: "<GeoJSON object type>" ,
            coordinates: [ <coordinates> ]
        }
     }
  }
}
Example of $geoIntersects

Select all the cities (we can image that our cities in this case are polygons not point) data that intersect with the Polygon defined by the coordinates array:

db.coll.find(
   {
     loc: {
       $geoIntersects: {
          $geometry: {
             type: "Polygon" ,
             coordinates: [
               [ [ 0, 0 ], [ 3, 6 ], [ 6, 1 ], [ 0, 0 ] ]
             ]
          }
       }
     }
   }
)