Elastic Search Geo Spatial search implementation Elastic Search Geo Spatial search implementation elasticsearch elasticsearch

Elastic Search Geo Spatial search implementation


Text & geo queries function separately of one another. Let's take a concrete example:

PUT restaurants{  "mappings": {    "properties": {      "location": {        "type": "geo_point"      },      "menu": {        "type": "text",        "fields": {          "keyword": {            "type": "keyword"          }        }      }    }  }}POST restaurants/_doc{  "name": "rest1",  "location": {    "lat": 40.739812,    "lon": -74.006201  },  "menu": [    "european",    "french",    "pizza"  ]}POST restaurants/_doc{  "name": "rest2",  "location": {    "lat": 40.7403963,    "lon": -73.9950026  },  "menu": [    "pizza",    "kebab"  ]}

One would then match a text field, use a geo_distance filter:

GET restaurants/_search{  "query": {    "bool": {      "must": [        {          "match": {            "menu": "pizza"          }        },        {          "geo_distance": {            "distance": "0.5mi",            "location": {              "lat": 40.7388,              "lon": -73.9982            }          }        },        {          "function_score": {            "query": {              "match_all": {}            },            "boost_mode": "avg",            "functions": [              {                "gauss": {                  "location": {                    "origin": {                      "lat": 40.7388,                      "lon": -73.9982                    },                    "scale": "0.5mi"                  }                }              }            ]          }        }      ]    }  }}

Since the geo_distance query only assigns a true/false value (--> score=1; only checking if the location is within a given radius), one may want to apply a gauss function_score to boost the locations closer to a given origin.

Finally, these scores are overridable by using a _geo_distance sort whereby you'd order by the proximity only (while of course keeping the match query intact):

...  "query: {...},  "sort": [    {      "_geo_distance": {        "location": {          "lat": 40.7388,          "lon": -73.9982        },        "order": "asc"      }    }  ]}