Skip to main content

geojson

The geojson template is a geospatial analyzer: instead of breaking text into word tokens, it reads a geometry and emits the set of S2 cell-ID terms that cover it. Those terms are what the inverted index stores and matches, so a JSON or GEOMETRY column indexed through geojson can be queried with spatial predicates such as containment, intersection and distance.

How it works

Geometries are supplied as GeoJSONPoint, LineString, Polygon and the other GeoJSON types. GeoJSON coordinates are [longitude, latitude]. The analyzer approximates each shape with a covering of S2 cells at a range of levels and emits the cell IDs as terms; a query shape is covered the same way, and rows match when their coverings overlap.

coding controls how a representative geometry is stored alongside the index terms so predicates can be evaluated precisely:

  • source (the default) keeps the original geometry and re-parses it at query time — exact, no precision loss, larger footprint.
  • s2point, s2latlngf64 and s2latlngu32 store an S2 encoding of the geometry instead. They are progressively more compact (and s2latlngu32 quantizes to ~centimetre precision), trading exactness for a smaller index. WKB ingest of a GEOMETRY column supports only s2point.

type controls what each shape is reduced to before terms are computed: shape (the default) indexes the full geometry, centroid indexes only its centroid point and point accepts point inputs only.

When to use geojson vs geopoint

Use geojson when rows hold arbitrary geometries — polygons, lines, multi-geometries — or points already expressed as GeoJSON. Reach for geopoint instead when every row is a single point whose latitude and longitude live in two separate fields of a JSON object; it builds the point directly without GeoJSON assembly. Both templates emit the same kind of S2 terms, so a point indexed either way is queried identically.

Options

OptionTypeDefaultDescription
typestringshapeWhat to index: shape, centroid or point
codingstringsourceGeometry encoding: source, s2point, s2latlngf64, s2latlngu32
minlevelinteger4Minimum S2 cell level (0–30)
maxlevelinteger23Maximum S2 cell level (0–30); ~1 m precision at level 23
maxcellsinteger20Maximum number of S2 cells in a covering
levelmodinteger1S2 level step (1, 2 or 3)
optimizeforspacebooleanfalseOptimize the S2 covering for space rather than speed

Usage

Create the dictionary, then attach it to a JSON or GEOMETRY column in a USING inverted index. A plain VARCHAR column is rejected for geo analyzers.

Query
CREATE TEXT SEARCH DICTIONARY geojson_shape (    template = 'geojson');

With coding = 's2point' the same geometries are stored as compact S2 points — the usual choice for a GEOMETRY column:

Query
CREATE TEXT SEARCH DICTIONARY geojson_s2 (    template = 'geojson',    coding = 's2point');

ts_lexize shows the cell-ID terms a geometry expands into — here a single point in central Berlin produces a covering of S2 cells from coarse to fine:

Query
SELECT ts_lexize(    'geojson_s2',    '{"type":"Point","coordinates":[13.405,52.52]}');
Result
 ts_lexize--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- {47b,47ac,47a9,47a84,47a85,47a854,47a851,47a851c,47a851d,47a851dc,47a851df,47a851dfc,47a851dff,47a851dfec,47a851dfed,47a851dfecc,47a851dfecd,47a851dfeccc,47a851dfecc9,47a851dfecc9c}

For the full indexing-and-query walkthrough — ST_Intersects, ST_Contains and distance predicates over both JSON and GEOMETRY columns — see Geospatial Search.

See also