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
}
})
Latitude coordinate (-90 to 90)
Longitude coordinate (-180 to 180)
Radius Search
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
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'
If true, returns documents inside the radius. If false, returns documents outside the radius.
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'
}
}
}
})
Polygon Search
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.
If true, returns documents inside the polygon. If false, returns documents outside the polygon.
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.
Combining with Text Search
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
Use Appropriate Radius
Smaller radius queries are faster:// Faster
{ radius: { value: 5, unit: 'km' } }
// Slower
{ radius: { value: 100, unit: 'km' } }
Avoid High Precision When Not Needed
Standard precision is sufficient for most use cases and much faster
Limit Polygon Complexity
Simple polygons (3-6 vertices) perform better than complex ones
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