If you’d like to take advantage of the geo-search abilities of ElasticSearch, you’ll need to use a Geo datatype. If you have an index with existing latitude and longitude fields, you can easily add a geo-point field.
First you will need to create a new field in your ElasticSearch index to hold your data. We will call ours coordinates
.
# Create the new "coordinates" field
INDEX="yourIndex"
ES_HOST="localhost:9200"
curl -X PUT "$ES_HOST/$INDEX/_mapping?pretty" -H 'Content-Type: application/json' -d'
{
"properties": {
"coordinates": { "type": "geo_point" }
}
}
'
Then we can run an Update by Query request to set the field for all matching docs. Here we assume that the existing latitude and longitude fields are called latitude
and longitude
, respectively.
# Update the new "coordinates" field with values from the existing
# "latitude" and "longitude" fields
INDEX="yourIndex"
ES_HOST="localhost:9200"
curl -X POST "$ES_HOST/$INDEX/_update_by_query?pretty" -H 'Content-Type: application/json' -d'
{
"query": {
"bool": {
"must_not": [
{ "exists": { "field": "coordinates" } }
],
"must": [
{ "exists": { "field": "latitude" } },
{ "range": { "latitude": { "gte": -90, "lte": 90 } } },
{ "exists": { "field": "longitude" } },
{ "range": { "longitude": { "gte": -180, "lte": 180 } } }
]
}
},
"script": {
"source": "ctx._source.coordinates = [ ctx._source.longitude, ctx._source.latitude ]",
"lang": "painless"
}
}
'
Note, I’ve added several “must” and “must_not” conditions to limit the query to run on eligible documents. In summary: documents must not already contain coordinates field, and the latitude
and longitude
fields must be present and within the acceptable ranges. This is to prevent exceptions from occurring, which would interrupt the process.
Be First to Comment