Episode 14 of 17

GeoJSON

Add location data to your API using GeoJSON — store coordinates, create geospatial indexes, and query documents by proximity.

GeoJSON

Many APIs need to handle location data — finding nearby restaurants, mapping delivery routes, or tracking assets. MongoDB has built-in support for geospatial data using the GeoJSON format. In this episode you will add location data to your ninja model and query by proximity.

What Is GeoJSON?

GeoJSON is a standard format for representing geographical features in JSON. MongoDB uses it for storing and querying location data.

{
    "type": "Point",
    "coordinates": [-73.9857, 40.7484]  // [longitude, latitude]
}

Note: GeoJSON uses [longitude, latitude] order — the reverse of what most mapping services show ([latitude, longitude]).

Updating the Schema

const ninjaSchema = new Schema({
    name: { type: String, required: true },
    rank: { type: Number, required: true },
    available: { type: Boolean, default: false },
    geometry: {
        type: {
            type: String,
            default: 'Point',
        },
        coordinates: {
            type: [Number],
            index: '2dsphere',
        },
    },
}, { timestamps: true });

Understanding the Geometry Field

FieldValuePurpose
geometry.type"Point"GeoJSON geometry type (Point, Polygon, LineString)
geometry.coordinates[lng, lat]Array of numbers representing the location
index: '2dsphere'Geospatial indexEnables proximity queries on this field

Saving a Ninja with Location

POST /api/ninjas
{
    "name": "Ryu",
    "rank": 5,
    "available": true,
    "geometry": {
        "type": "Point",
        "coordinates": [-73.9857, 40.7484]
    }
}

Finding Nearby Ninjas

router.get('/near', async (req, res, next) => {
    try {
        const { lng, lat, maxDistance } = req.query;

        const ninjas = await Ninja.find({
            geometry: {
                $near: {
                    $geometry: {
                        type: 'Point',
                        coordinates: [parseFloat(lng), parseFloat(lat)],
                    },
                    $maxDistance: parseInt(maxDistance) || 10000,
                },
            },
        });

        res.json(ninjas);
    } catch (err) {
        next(err);
    }
});

Query Operators

OperatorPurpose
$nearFind documents near a point, sorted by distance
$geoWithinFind documents within a shape (circle, polygon)
$maxDistanceMaximum distance in meters from the point
$minDistanceMinimum distance in meters from the point

Testing

GET /api/ninjas/near?lng=-73.9857&lat=40.7484&maxDistance=5000

This returns all ninjas within 5000 meters of the specified coordinates, sorted by proximity (closest first).

Key Takeaways

  • GeoJSON stores location data as { type: "Point", coordinates: [lng, lat] }
  • A 2dsphere index is required for geospatial queries
  • $near finds documents sorted by distance from a point
  • $maxDistance limits results to a radius in meters
  • Coordinates are in [longitude, latitude] order — the reverse of most mapping services