Geopoint field type
editGeopoint field type
editFields of type geo_point
accept latitude-longitude pairs, which can be used:
-
to find geopoints within a bounding box,
within a certain distance of a central point,
or within a
geo_shape
query (for example, points in a polygon). - to aggregate documents by distance from a central point.
-
to aggregate documents by geographic grids: either
geo_hash
,geo_tile
orgeo_hex
. -
to aggregate geopoints into a track using the metrics aggregation
geo_line
. - to integrate distance into a document’s relevance score.
- to sort documents by distance.
As with geo_shape and point, geo_point
can be specified in GeoJSON
and Well-Known Text formats.
However, there are a number of additional formats that are supported for convenience and historical reasons.
In total there are six ways that a geopoint may be specified, as demonstrated below:
response = client.indices.create( index: 'my-index-000001', body: { mappings: { properties: { location: { type: 'geo_point' } } } } ) puts response response = client.index( index: 'my-index-000001', id: 1, body: { text: 'Geopoint as an object using GeoJSON format', location: { type: 'Point', coordinates: [ -71.34, 41.12 ] } } ) puts response response = client.index( index: 'my-index-000001', id: 2, body: { text: 'Geopoint as a WKT POINT primitive', location: 'POINT (-71.34 41.12)' } ) puts response response = client.index( index: 'my-index-000001', id: 3, body: { text: "Geopoint as an object with 'lat' and 'lon' keys", location: { lat: 41.12, lon: -71.34 } } ) puts response response = client.index( index: 'my-index-000001', id: 4, body: { text: 'Geopoint as an array', location: [ -71.34, 41.12 ] } ) puts response response = client.index( index: 'my-index-000001', id: 5, body: { text: 'Geopoint as a string', location: '41.12,-71.34' } ) puts response response = client.index( index: 'my-index-000001', id: 6, body: { text: 'Geopoint as a geohash', location: 'drm3btev3e86' } ) puts response response = client.search( index: 'my-index-000001', body: { query: { geo_bounding_box: { location: { top_left: { lat: 42, lon: -72 }, bottom_right: { lat: 40, lon: -74 } } } } } ) puts response
PUT my-index-000001 { "mappings": { "properties": { "location": { "type": "geo_point" } } } } PUT my-index-000001/_doc/1 { "text": "Geopoint as an object using GeoJSON format", "location": { "type": "Point", "coordinates": [-71.34, 41.12] } } PUT my-index-000001/_doc/2 { "text": "Geopoint as a WKT POINT primitive", "location" : "POINT (-71.34 41.12)" } PUT my-index-000001/_doc/3 { "text": "Geopoint as an object with 'lat' and 'lon' keys", "location": { "lat": 41.12, "lon": -71.34 } } PUT my-index-000001/_doc/4 { "text": "Geopoint as an array", "location": [ -71.34, 41.12 ] } PUT my-index-000001/_doc/5 { "text": "Geopoint as a string", "location": "41.12,-71.34" } PUT my-index-000001/_doc/6 { "text": "Geopoint as a geohash", "location": "drm3btev3e86" } GET my-index-000001/_search { "query": { "geo_bounding_box": { "location": { "top_left": { "lat": 42, "lon": -72 }, "bottom_right": { "lat": 40, "lon": -74 } } } } }
Geopoint expressed as an object, in GeoJSON format, with |
|
Geopoint expressed as a Well-Known Text
POINT with the format: |
|
Geopoint expressed as an object, with |
|
Geopoint expressed as an array with the format: [ |
|
Geopoint expressed as a string with the format: |
|
Geopoint expressed as a geohash. |
|
A geo-bounding box query which finds all geopoints that fall inside the box. |
Geopoints expressed as an array or string
Please note that string geopoints are ordered as lat,lon
, while array
geopoints, GeoJSON and WKT are ordered as the reverse: lon,lat
.
The reasons for this are historical. Geographers traditionally write latitude
before longitude
, while recent formats specified for geographic data like
GeoJSON and Well-Known Text
order longitude
before latitude
(easting before northing) in order to match
the mathematical convention of ordering x
before y
.
A point can be expressed as a geohash. Geohashes are base32 encoded strings of the bits of the latitude and longitude interleaved. Each character in a geohash adds additional 5 bits to the precision. So the longer the hash, the more precise it is. For the indexing purposed geohashs are translated into latitude-longitude pairs. During this process only first 12 characters are used, so specifying more than 12 characters in a geohash doesn’t increase the precision. The 12 characters provide 60 bits, which should reduce a possible error to less than 2cm.
Parameters for geo_point
fields
editThe following parameters are accepted by geo_point
fields:
If |
|
|
If |
Should the field be quickly searchable? Accepts |
|
Accepts an geopoint value which is substituted for any explicit |
|
|
Defines what to do if the script defined by the |
|
If this parameter is set, then the field will index values generated by this script, rather than reading the values directly from the source. If a value is set for this field on the input document, then the document will be rejected with an error. Scripts are in the same format as their runtime equivalent, and should emit points as a pair of (lat, lon) double values. |
Using geopoints in scripts
editWhen accessing the value of a geopoint in a script, the value is returned as
a GeoPoint
object, which allows access to the .lat
and .lon
values
respectively:
def geopoint = doc['location'].value; def lat = geopoint.lat; def lon = geopoint.lon;
For performance reasons, it is better to access the lat/lon values directly:
def lat = doc['location'].lat; def lon = doc['location'].lon;
Synthetic source
editSynthetic _source
is Generally Available only for TSDB indices
(indices that have index.mode
set to time_series
). For other indices
synthetic _source
is in technical preview. Features in technical preview may
be changed or removed in a future release. Elastic will apply best effort to fix
any issues, but features in technical preview are not subject to the support SLA
of official GA features.
geo_point
fields support synthetic _source
in their
default configuration. Synthetic _source
cannot be used together with
ignore_malformed
, copy_to
, or with
doc_values
disabled.
Synthetic source always sorts geo_point
fields (first by latitude and then
longitude) and reduces them to their stored precision. For example:
response = client.indices.create( index: 'idx', body: { mappings: { _source: { mode: 'synthetic' }, properties: { point: { type: 'geo_point' } } } } ) puts response response = client.index( index: 'idx', id: 1, body: { point: [ { lat: -90, lon: -80 }, { lat: 10, lon: 30 } ] } ) puts response
PUT idx { "mappings": { "_source": { "mode": "synthetic" }, "properties": { "point": { "type": "geo_point" } } } } PUT idx/_doc/1 { "point": [ {"lat":-90, "lon":-80}, {"lat":10, "lon":30} ] }
Will become:
{ "point": [ {"lat":-90.0, "lon":-80.00000000931323}, {"lat":9.999999990686774, "lon":29.999999972060323} ] }