Search Geospatially
On this page
Overview
In this guide, you can learn how to search geospatial data with the MongoDB Java Driver, and the different geospatial data formats supported by MongoDB.
Geospatial data is data that represents a geographic location on the surface of the Earth. Examples of geospatial data include:
Locations of movie theaters
Borders of countries
Routes of bicycle rides
Dog exercise areas in New York City
Coordinates on Earth
To store and query your geospatial data in MongoDB, use GeoJSON. GeoJSON is a data format created by the Internet Engineering Task Force (IETF).
Here is the location of MongoDB headquarters in GeoJSON:
"MongoDB Headquarters" : { "type": "point", "coordinates": [-73.986805, 40.7620853] }
For definitive information on GeoJSON, see the official IETF specification.
GeoJSON Positions
A position represents a single place on Earth, and exists in code as an array containing two or three number values:
Longitude in the first position (required)
Latitude in the second position (required)
Elevation in the third position (optional)
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.
GeoJSON Types
Your GeoJSON object's type determines its geometric shape. 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. This could represent the location of a sculpture.LineString
: an array of two or more positions, thus forming a series of line segments. This could represent the route of the Great Wall of China.Polygon
: an array of positions in which the first and last position are the same, thus enclosing some space. This could represent the land within Vatican City.
To learn more about the shapes you can use in MongoDB, see the GeoJSON manual entry.
Index
To query data stored in the GeoJSON format, add the field containing
GeoJSON data to a 2dsphere
index. The following snippet creates a
2dsphere
index on the location.geo
field using the Indexes
builder:
// <MongoCollection setup code here> collection.createIndex(Indexes.geo2dsphere("location.geo"));
For more information on the Indexes
builder, see our
guide on the Indexes builder.
Coordinates on a 2D Plane
You can store geospatial data using x
and y
coordinates on
a two-dimensional Euclidean plane. We refer to coordinates on a two-dimensional
plane as "legacy coordinate pairs".
Legacy coordinate pairs have the following structure:
"<field name>" : [ x, y ]
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.
Index
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 using the Indexes
builder:
// <MongoCollection setup code here> collection.createIndex(Indexes.geo2d("coordinates"));
For more information on the Indexes
builder, see our
guide on the Indexes builder.
For more information on legacy coordinate pairs, see the MongoDB Server manual page on legacy coordinate pairs.
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.
Geospatial Queries
Geospatial queries consist of a query operator and GeoJSON shapes as query parameters.
Query Operators
To query your geospatial data, use one of the following query operators:
$near
$geoWithin
$nearSphere
$geoIntersects
requires a 2dsphere index
You can specify these query operators in the MongoDB Java driver with the
near()
, geoWithin()
, nearSphere()
, and geoIntersects()
utility
methods of the Filters
builder class.
For more information on geospatial query operators, see the manual entry for geospatial queries.
For more information on Filters
, see our
guide on the Filters builder.
Query Parameters
To specify a shape to use in a geospatial query, use the
Position
, Point
, LineString
, and Polygon
classes of the MongoDB
Java driver.
For a full list of the GeoJSON shapes available in the MongoDB Java driver, see the GeoJSON package API Documentation.
Examples
The following examples use the MongoDB Atlas sample dataset. You can learn how to set up your own free-tier Atlas cluster and how to load the sample dataset in our quick start guide.
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 examples require the following imports:
import java.util.Arrays; import org.bson.conversions.Bson; import com.mongodb.client.model.geojson.Point; import com.mongodb.client.model.geojson.Polygon; import com.mongodb.client.model.geojson.Position; import static com.mongodb.client.model.Filters.near; import static com.mongodb.client.model.Filters.geoWithin; import static com.mongodb.client.model.Projections.fields; import static com.mongodb.client.model.Projections.include; import static com.mongodb.client.model.Projections.excludeId;
You can find the source code for the examples on Github here.
Query by Proximity
To search for and return documents from nearest to farthest from a point, use
the near()
static utility method of the Filters
builder class. The
near()
method constructs a query with the $near
query operator.
The following example queries for theaters between 10,000
and 5,000
meters from the
Great Lawn of Central Park.
// Add your MongoClient setup code here MongoDatabase database = mongoClient.getDatabase("sample_mflix"); MongoCollection<Document> collection = database.getCollection("theaters"); Point centralPark = new Point(new Position(-73.9667, 40.78)); // Creates a query that matches all locations between 5,000 and 10,000 meters from the specified Point Bson query = near("location.geo", centralPark, 10000.0, 5000.0); // Creates a projection to include only the "location.address.city" field in the results Bson projection = fields(include("location.address.city"), excludeId()); // Prints the projected field of the results from the geospatial query as JSON collection.find(query) .projection(projection) .forEach(doc -> System.out.println(doc.toJson()));
The output of the code snippet should look something like this:
{"location": {"address": {"city": "Bronx"}}} {"location": {"address": {"city": "New York"}}} {"location": {"address": {"city": "New York"}}} {"location": {"address": {"city": "Long Island City"}}} {"location": {"address": {"city": "New York"}}} {"location": {"address": {"city": "Secaucus"}}} {"location": {"address": {"city": "Jersey City"}}} {"location": {"address": {"city": "Elmhurst"}}} {"location": {"address": {"city": "Flushing"}}} {"location": {"address": {"city": "Flushing"}}} {"location": {"address": {"city": "Flushing"}}} {"location": {"address": {"city": "Elmhurst"}}}
Tip
Fun Fact
MongoDB uses the same reference system as GPS satellites to calculate geometries over the Earth.
For more information on the $near
operator, see
the reference documentation for $near.
For more information on Filters
,
see our guide on the Filters builder.
Query Within a Range
To search for geospatial data within a specified shape use the geoWithin()
static utility method of the Filters
builder class. The geoWithin()
method constructs a query with the $geoWithin
query operator.
The following example searches for movie theaters in a section of Long Island.
// Add your MongoCollection setup code here // Creates a set of points that defines the bounds of a geospatial shape Polygon longIslandTriangle = new Polygon(Arrays.asList(new Position(-72, 40), new Position(-74, 41), new Position(-72, 39), new Position(-72, 40))); // Creates a projection to include only the "location.address.city" field in the results Bson projection = fields(include("location.address.city"), excludeId()); // Creates a query that matches documents containing "location.geo" values within the specified bounds Bson geoWithinComparison = geoWithin("location.geo", longIslandTriangle); // Prints the projected field of the results from the geolocation query as JSON collection.find(geoWithinComparison) .projection(projection) .forEach(doc -> System.out.println(doc.toJson()));
The output of the code snippet should look something like this:
{"location": {"address": {"city": "Baldwin"}}} {"location": {"address": {"city": "Levittown"}}} {"location": {"address": {"city": "Westbury"}}} {"location": {"address": {"city": "Mount Vernon"}}} {"location": {"address": {"city": "Massapequa"}}}
The following figure shows the polygon defined by the
longIslandTriangle
variable and dots representing the locations of
the movie theaters returned by our query.
For more information on the $geoWithin
operator, see the
reference documentation for $geoWithin
For more information on the operators you can use in your query, see the MongoDB Server manual page on geospatial query operators