How to Use $geoWithin in MongoDB for Geospatial Queries
Use the
$geoWithin operator in MongoDB to find documents where a geospatial field is inside a specified shape like a polygon or circle. It works with GeoJSON objects or legacy coordinate pairs inside a $geoWithin query to filter locations within boundaries.Syntax
The $geoWithin operator is used inside a find() query to filter documents with geospatial data inside a specified shape.
Basic syntax:
{ locationField: { $geoWithin: { $geometry: { type: "Polygon", coordinates: [...] } } } }- Finds documents wherelocationFieldis inside the polygon.{ locationField: { $geoWithin: { $centerSphere: [ [lng, lat], radiusInRadians ] } } }- Finds documents inside a circle defined by center and radius.
The locationField must be indexed with a 2dsphere index for GeoJSON data.
mongodb
db.places.find({
location: {
$geoWithin: {
$geometry: {
type: "Polygon",
coordinates: [
[
[ -73.97, 40.77 ],
[ -73.88, 40.78 ],
[ -73.88, 40.68 ],
[ -73.97, 40.68 ],
[ -73.97, 40.77 ]
]
]
}
}
}
})Example
This example shows how to find places inside a polygon area using $geoWithin. The location field stores GeoJSON points.
mongodb
use testdb // Create collection and add 2dsphere index db.places.createIndex({ location: "2dsphere" }) // Insert sample documents db.places.insertMany([ { name: "Park", location: { type: "Point", coordinates: [ -73.95, 40.75 ] } }, { name: "Museum", location: { type: "Point", coordinates: [ -73.99, 40.76 ] } }, { name: "Cafe", location: { type: "Point", coordinates: [ -73.87, 40.70 ] } } ]) // Query places within polygon const results = db.places.find({ location: { $geoWithin: { $geometry: { type: "Polygon", coordinates: [[ [ -73.97, 40.77 ], [ -73.88, 40.78 ], [ -73.88, 40.68 ], [ -73.97, 40.68 ], [ -73.97, 40.77 ] ]] } } } }).toArray() printjson(results)
Output
[
{
"_id": ObjectId("..."),
"name": "Park",
"location": { "type": "Point", "coordinates": [ -73.95, 40.75 ] }
},
{
"_id": ObjectId("..."),
"name": "Cafe",
"location": { "type": "Point", "coordinates": [ -73.87, 40.70 ] }
}
]
Common Pitfalls
- Missing 2dsphere index: The
$geoWithinquery requires a 2dsphere index on the location field; otherwise, it will fail or be slow. - Incorrect coordinate order: GeoJSON uses
[longitude, latitude]order, not latitude then longitude. - Shape closure: Polygons must have the first and last coordinate points identical to close the shape.
- Using legacy coordinate pairs with GeoJSON: Mixing legacy coordinate pairs and GeoJSON formats can cause errors.
mongodb
/* Wrong: Missing 2dsphere index */ db.places.find({ location: { $geoWithin: { $geometry: { type: "Polygon", coordinates: [[ [ -73.97, 40.77 ], [ -73.88, 40.78 ], [ -73.88, 40.68 ], [ -73.97, 40.68 ], [ -73.97, 40.77 ] ]] } } } }) /* Right: Create 2dsphere index first */ db.places.createIndex({ location: "2dsphere" })
Quick Reference
$geoWithin: Finds documents with locations inside a geometry.$geometry: Defines GeoJSON shape (Polygon, MultiPolygon, etc.).$centerSphere: Defines a circle with center and radius in radians.- Always use
2dsphereindex on geospatial fields. - Coordinates order is
[longitude, latitude].
Key Takeaways
Use $geoWithin to find documents with locations inside a specified GeoJSON shape.
Always create a 2dsphere index on the geospatial field before querying with $geoWithin.
Coordinates in GeoJSON must be in [longitude, latitude] order.
Polygons must be closed by repeating the first coordinate at the end.
Use $geometry for polygons and $centerSphere for circular areas in $geoWithin queries.