Skip to main content

Geosearch

Orama supports geospatial search capabilities, allowing you to filter results based on geographic locations using radius and polygon-based queries.

Geopoint Schema

Define geopoint properties in your schema:
import { create, insert, search } from '@orama/orama'

const db = create({
  schema: {
    name: 'string',
    location: 'geopoint'
  }
})

insert(db, {
  name: 'Central Park',
  location: {
    lat: 40.785091,
    lon: -73.968285
  }
})
lat
number
required
Latitude coordinate (-90 to 90)
lon
number
required
Longitude coordinate (-180 to 180)
Search for documents within a specific radius from a center point:
const results = search(db, {
  where: {
    location: {
      radius: {
        coordinates: {
          lat: 40.7128,
          lon: -74.0060
        },
        value: 5,
        unit: 'km'
      }
    }
  }
})

Radius Parameters

radius.coordinates
{lat: number, lon: number}
required
The center point of the search radius
radius.value
number
required
The radius distance from the center point
radius.unit
GeosearchDistanceUnit
default:"'m'"
The unit of measurement for the radius. Options: 'cm', 'm', 'km', 'ft', 'yd', 'mi'
radius.inside
boolean
default:"true"
If true, returns documents inside the radius. If false, returns documents outside the radius.
radius.highPrecision
boolean
default:"false"
Enable high-precision distance calculations (slower but more accurate)

Distance Units

Orama supports various distance units:
const results = search(db, {
  where: {
    location: {
      radius: {
        coordinates: { lat: 40.7128, lon: -74.0060 },
        value: 5,
        unit: 'km'
      }
    }
  }
})
Search for documents within a polygon defined by multiple coordinates:
const results = search(db, {
  where: {
    location: {
      polygon: {
        coordinates: [
          { lat: 40.7128, lon: -74.0060 },  // Point 1
          { lat: 40.7580, lon: -73.9855 },  // Point 2
          { lat: 40.7489, lon: -73.9680 },  // Point 3
          { lat: 40.7128, lon: -74.0060 }   // Close the polygon
        ]
      }
    }
  }
})
The polygon must be closed - the first and last coordinates should be the same point.

Polygon Parameters

polygon.coordinates
Array<{lat: number, lon: number}>
required
Array of coordinate points defining the polygon vertices. First and last points should match to close the polygon.
polygon.inside
boolean
default:"true"
If true, returns documents inside the polygon. If false, returns documents outside the polygon.
polygon.highPrecision
boolean
default:"false"
Enable high-precision polygon calculations

Outside Radius/Polygon

Find documents outside a specific area:
const results = search(db, {
  where: {
    location: {
      radius: {
        coordinates: { lat: 40.7128, lon: -74.0060 },
        value: 10,
        unit: 'km',
        inside: false  // Documents OUTSIDE the radius
      }
    }
  }
})

High Precision Mode

Enable high-precision calculations for more accurate results:
const results = search(db, {
  where: {
    location: {
      radius: {
        coordinates: { lat: 40.7128, lon: -74.0060 },
        value: 5,
        unit: 'km',
        highPrecision: true  // More accurate distance calculations
      }
    }
  }
})
High precision mode provides more accurate results but is slower. Use it only when precision is critical.
Combine geosearch with full-text search:
const results = search(db, {
  term: 'coffee shop',
  where: {
    location: {
      radius: {
        coordinates: { lat: 40.7128, lon: -74.0060 },
        value: 2,
        unit: 'km'
      }
    }
  }
})

Geosearch with Other Filters

Combine geosearch with other filter types:
const db = create({
  schema: {
    name: 'string',
    category: 'string',
    rating: 'number',
    location: 'geopoint'
  }
})

const results = search(db, {
  term: 'restaurant',
  where: {
    and: [
      {
        location: {
          radius: {
            coordinates: { lat: 40.7128, lon: -74.0060 },
            value: 5,
            unit: 'km'
          }
        }
      },
      {
        rating: {
          gte: 4.0
        }
      },
      {
        category: 'italian'
      }
    ]
  }
})

Distance Scoring

When performing geosearch-only queries (no search term), results are scored by distance:
// Geosearch-only query - results scored by distance
const results = search(db, {
  where: {
    location: {
      radius: {
        coordinates: { lat: 40.7128, lon: -74.0060 },
        value: 10,
        unit: 'km'
      }
    }
  }
})

// Results are sorted by proximity to the center point
console.log(results.hits)
// Closest location will have the highest score
Geosearch-only queries automatically score results by distance from the center point, with closer locations receiving higher scores.

Multiple Geopoint Properties

You can have multiple geopoint properties in your schema:
const db = create({
  schema: {
    name: 'string',
    pickupLocation: 'geopoint',
    deliveryLocation: 'geopoint'
  }
})

insert(db, {
  name: 'Delivery Order #123',
  pickupLocation: { lat: 40.7128, lon: -74.0060 },
  deliveryLocation: { lat: 40.7580, lon: -73.9855 }
})

// Search by pickup location
const results = search(db, {
  where: {
    pickupLocation: {
      radius: {
        coordinates: { lat: 40.7128, lon: -74.0060 },
        value: 1,
        unit: 'km'
      }
    }
  }
})

Common Use Cases

Store Locator

Find nearby stores, restaurants, or businesses within a radius

Delivery Zones

Check if addresses fall within delivery polygons

Real Estate Search

Find properties near specific landmarks or within neighborhoods

Event Discovery

Discover events happening nearby

Performance Considerations

1

Use Appropriate Radius

Smaller radius queries are faster:
// Faster
{ radius: { value: 5, unit: 'km' } }

// Slower
{ radius: { value: 100, unit: 'km' } }
2

Avoid High Precision When Not Needed

Standard precision is sufficient for most use cases and much faster
3

Limit Polygon Complexity

Simple polygons (3-6 vertices) perform better than complex ones
4

Combine with Other Filters

Pre-filter by other criteria before applying geosearch:
where: {
  and: [
    { category: 'restaurant' },  // Filter first
    { location: { radius: {...} } }  // Then geosearch
  ]
}

Filters

Combine geosearch with other filter types

Sorting

Sort geosearch results by distance or other properties

Full-Text Search

Combine geosearch with text search

Facets

Generate location-based facets

Build docs developers (and LLMs) love