Docs Menu

Docs HomeGo

Work with Geospatial Data

On this page

  • Overview
  • Store Geospatial Data
  • GeoJSON
  • Legacy Coordinate Pairs
  • Geospatial Indexes
  • 2dsphere
  • 2d
  • Geospatial Queries
  • Query Operators
  • Examples
  • Query by Proximity
  • Query Within a Range
  • Additional Resources

In this guide, you can learn how to work with geospatial data; data formats, indexes, and queries. Geospatial data represents a geographic location on the surface of the Earth, or data on a Euclidean plane.

Examples of geospatial data include:

  • Locations of movie theaters

  • Borders of countries

  • Routes of bicycle rides

  • Dog exercise areas in New York City

  • Points on a graph

All geospatial data in MongoDB is stored in one of the following formats:

  • GeoJSON, a format that represents geospatial data on an earth-like sphere.

  • Legacy Coordinate Pair, a format that represents geospatial data on a Euclidean plane.

Use GeoJSON to store data that represents geospatial information on an earth-like sphere. GeoJSON is composed of one or more positions and a type.

A position represents a single place on Earth and exists in code as an array containing the following values:

  • Longitude in the first position (required)

  • Latitude in the second position (required)

  • Elevation in the third position (optional)

The following is the position of the MongoDB Headquarters in New York City, NY.

[]float64{-73.986805, 40.7620853}

Important

Longitude then Latitude

GeoJSON orders coordinates as longitude first and latitude second. This may be surprising as geographic coordinate system conventions generally list latitude first and longitude second. Make sure to check what format any other tools you are working with use. Popular tools such as OpenStreetMap and Google Maps list coordinates as latitude first and longitude second.

Your GeoJSON object's type determines the geometric shape it represents. Geometric shapes are made up of positions.

Here are some common GeoJSON types and how you can specify them with positions:

  • Point: a single position. The following Point represents the location of the MongoDB Headquarters:

    bson.D{
    {"name", "MongoDB HQ"},
    {"location", bson.D{
    {"type", "Point"},
    {"coordinates", []float64{-73.986805, 40.7620853}},
    }},
    }
  • LineString: an array of two or more positions that forms a series of line segments. A LineString can represent a path, route, border, or any other linear geospatial data. The following LineString represents a segment of the Great Wall of China:

    bson.D{
    {"name", "Great Wall of China"},
    {"location", bson.D{
    {"type", "LineString"},
    {"coordinates", [][]float64{
    {116.572, 40.430},
    {116.570, 40.434},
    {116.567, 40.436},
    {116.566, 40.441},
    }}},
    },
    }
  • Polygon: an array of positions in which the first and last position are the same and enclose some space. The following Polygon represents the land within Vatican City:

    bson.D{
    {"name", "Vatican City"},
    {"location", bson.D{
    {"type", "Polygon"},
    {"coordinates", [][][]float64{{
    {116.572, 40.430},
    {116.570, 40.434},
    {116.567, 40.436},
    {116.572, 40.430},
    }}},
    }},
    }

To learn more about the GeoJSON types you can use in MongoDB, see the GeoJSON manual entry.

For definitive information on GeoJSON, see the official IETF specification.

Use legacy coordinate pairs to store data that represents geospatial information on a two-dimensional Euclidean plane.

Your field should contain an array of two values in which the first represents the x axis value and the second represents the y axis value.

bson.D{{"center", []int16{0, 0}}}

For more information on legacy coordinate pairs, see the MongoDB server manual page on legacy coordinate pairs.

To enable querying on geospatial data, you must create an index that corresponds to the data format. The following index types enable geospatial queries:

  • 2dsphere for GeoJSON data

  • 2d for legacy coordinate pairs

To query data stored in the GeoJSON format, add the field containing both the type and coordinates to a 2dsphere index. The following snippet creates a 2dsphere index on the location field:

indexModel := mongo.IndexModel{
Keys: bson.D{{"location", "2dsphere"}},
}
name, err := coll.Indexes().CreateOne(context.TODO(), indexModel)
if err != nil {
panic(err)
}

To query data stored as legacy coordinate pairs, you must add the field containing legacy coordinate pairs to a 2d index. The following snippet creates a 2d index on the coordinates field:

indexModel := mongo.IndexModel{
Keys: bson.D{{"location.coordinates", "2d"}},
}
name, err := coll.Indexes().CreateOne(context.TODO(), indexModel)
if err != nil {
panic(err)
}

To perform a geospatial query, create a query filter with a field name and a geospatial query operator. You can specify additional options for certain geospatial query operators to limit the documents returned.

If you have not done so, you must create a geospatial index to enable geospatial queries.

Tip

Supported Operators

Spherical (2dsphere) and flat (2d) indexes support some, but not all, of the same query operators. For a full list of operators and their index compatibility, see the manual entry for geospatial queries.

To query your geospatial data, use one of the following query operators:

  • $near

  • $geoWithin

  • $nearSphere

  • $geoIntersects requires a 2dsphere index

When using the $near operator, you can specify the following distance operators:

  • $minDistance

  • $maxDistance

When using the $geoWithin operator, you can specify the following shape operators:

  • $box

  • $polygon

  • $center

  • $centerSphere

For more information on geospatial query operators, see the manual entry for geospatial queries.

The following examples use the MongoDB Atlas sample dataset. You can load sample datasets into your database on the free tier of MongoDB Atlas by following the Get Started with Atlas Guide or you can import the sample dataset into a local MongoDB instance.

The examples use the theaters collection in the sample_mflix database from the sample dataset. The theaters collection contains a 2dsphere index on the location.geo field.

The following example queries for documents with a location.geo field within 1000 meters of the MongoDB Headquarters in New York City, NY. It returns documents from nearest to farthest.

mongoDBHQ := bson.D{{"type", "Point"}, {"coordinates", []float64{-73.986805, 40.7620853}}}
filter := bson.D{
{"location.geo", bson.D{
{"$near", bson.D{
{"$geometry", mongoDBHQ},
{"$maxDistance", 1000},
}},
}},
}
var places []bson.D
output, err := coll.Find(context.TODO(), filter)
if err = output.All(context.TODO(), &places); err != nil {
panic(err)
}
fmt.Println(places)
[
[{_id ObjectID(...)} {theaterId 1908} {location [{address [...]} {geo [{type Point} {coordinates [-73.983487 40.76078]}]}]}]
[{_id ObjectID(...)} {theaterId 1448} {location [{address [...]} {geo [{type Point} {coordinates [-73.982094 40.76988]}]}]}]
]

The following example queries for documents with a location.geo field no closer than 2000 meters and no farther than 3000 meters of the MongoDB Headquarters in New York City, NY. It returns documents from nearest to farthest.

mongoDBHQ := bson.D{{"type", "Point"}, {"coordinates", []float64{-73.986805, 40.7620853}}}
filter := bson.D{
{"location.geo",
bson.D{
{"$nearSphere", bson.D{
{"$geometry", MongoDBHQ},
{"$minDistance", 2000},
{"$maxDistance", 3000},
}},
}},
}
var places bson.D
err := coll.Find(context.TODO(), filter).Decode(&places)
if err != nil {
panic(err)
}
fmt.Println(places)
[[{_id ObjectID(...)} {theaterId 482} {location [...]} {geo [{type Point} {coordinates [-73.99295 40.74194]}]}]}]]
←  Time Series CollectionsFAQ →