Skip to main content
Related: Relation, Schema, Relation Guide, Cookbook Geo search lets you filter, sort, and boost documents by geographic location using Typesense’s native geopoint type. All geo chainers are immutable, copy-on-write, and composable with existing where / order chainers. where_geo, order_geo and order_eval work directly on model classes and on relations. Building a query makes no HTTP request. Gem 30.9.0 targets Typesense 30.x and is tested against 30.2. Radius/polygon filters, conditional viewport ranking, distance ordering and hit metadata are qualified against that server release.

Schema setup

Declare a :geopoint attribute on your model. Typesense expects the value as a [lat, lng] array.
For models with multiple coordinate fields, use [:geopoint] for an array of geopoints:

where_geo — geo filtering

Filter results by geographic proximity (radius) or containment (polygon). Compiles to Typesense filter_by.

Radius filter

  • lat / lng: reference point coordinates
  • radius: string with unit — "10 km" or "5 mi"

Polygon filter

  • Requires 3 or more [lat, lng] points
  • Points define the polygon boundary; Typesense returns documents inside it

Chaining with where

Multiple where and where_geo calls compose with AND semantics.

Validation

  • Field must be declared as :geopoint or [:geopoint]
  • Coordinates are validated: lat in [-90, 90], lng in [-180, 180]
  • Radius format must match "<number> km" or "<number> mi"
  • within_radius: and within_polygon: are mutually exclusive
  • Polygon must have at least 3 points, each as [lat, lng]

order_geo — distance sorting

Sort results by distance from a reference point. Compiles to Typesense sort_by with the geopoint distance syntax.
Default direction is :asc (nearest first). Use direction: :desc for farthest first.

Advanced options

  • exclude_radius: exclude results within this distance from distance scoring
  • precision: bucket precision for distance sort

Chaining with order

Duplicate sort fields are de-duplicated with last-wins semantics.

order_eval — conditional sort expressions

Sort by a Typesense _eval() expression. Useful for boosting documents that match a condition (e.g., inside a map viewport polygon) without filtering them out.

Simple expression

Compiles to: _eval(location:(54.72,25.35, ...)):desc Default direction is :desc (matching documents first).

Weighted multi-expression

Compiles to: _eval([ (location:(...)):3, (rating:>4.5):1 ]):desc

Viewport boost pattern

The canonical map search pattern: boost documents in the visible viewport, then sort by distance as a tiebreaker.
Documents inside the polygon rank first; within each group, nearest-first. This ranks documents outside the viewport after those inside it. Add where_geo when outside documents must be excluded; ordering alone does not constrain the result set.

geo_distance_meters — distance on results

When order_geo is used, Typesense includes distance metadata on each hit. The gem exposes this via the geo_distance_meters method on hydrated result objects.
  • Returns a Hash mapping field name to distance in meters, e.g. { "location" => 1234 }
  • Only present when the response includes geo_distance_meters (i.e., when a geo sort is active)
  • Works for both flat and grouped results

Full example

Troubleshooting

  • “field must be declared as :geopoint”: ensure the attribute is declared with :geopoint type in your model
  • No geo_distance_meters on hits: this metadata is only present when sort_by includes a geopoint distance sort — use order_geo
  • Invalid radius format: use a string like "10 km" or "5 mi" — bare numbers or other units are rejected
The gem repository includes a database-free CLI example:
This compiles radius/polygon, viewport/distance, vector and highlighting requests and checks explicit metadata fixtures. Follow the demo README to opt into --live against a disposable loopback server; the script owns and cleans up unique collections. Compilation alone does not prove live results. Backlinks: Relation, Schema, Deferred Features