Geo distance search using Elasticsearch

Anurag Srivastava
Level Up Coding
Published in
5 min readMay 20, 2020

--

In this blog, I am going to cover how you can measure distance using Elasticsearch. Geo distance measurement is a very important aspect of many apps. Now let us take a very simple example where when we move to any new location, Google starts showing us the nearest attractions or any cab aggregating service uses your current location to book the nearest cab for you. Geo distance based search is also a very important use case where we try to find the nearest restaurant, ATM, hospital, or practically anything.

So until now we have discussed different use cases where geo distance based search is very important, and for some businesses it is critical. But the question arises: How do you actually perform geo search? So let us find out how we can perform a geo search in Elasticsearch.

Elasticsearch also supports geo data types, and these can be of two types that are geo-point and geo-shape. In this blog, we will focus on geo-point which is a point representation and a point is nothing but a geocoordinate having latitude and longitude. Although Elasticsearch accepts data without explicit mapping creation for geodata we need to explicitly create the mapping as it is the first step for executing geo queries.

But before creating the mapping, let us understand what we are going to achieve in this blog. So the idea is to create an index in Elasticsearch along with a field of a geo-point type that will hold the latitude and longitude. Then we will add some geo data representing a fake location like some parking locations. After adding those parking locations we will pass an arbitrary user current location and will try to find the nearest parking location.

So let us start with an index creation along with the location field mapping of geo-point type. We need to execute the following command to create an index along with location mapping:

PUT parking_locations
{
"mappings": {
"properties": {
"location": {
"type": "geo_point"
}
}
}
}

After executing the above command we can get the following response on success:

{
"acknowledged" : true,
"shards_acknowledged" : true,
"index" : "parking_locations"
}

Our parking location index is created along with the mapping of the location field. Now let us add some arbitrary locations so that we can apply geo search later. We will be adding the following data:

Parking 1 28.594817, 77.046608
Parking 2 28.593168, 77.041244
Parking 3 28.601345, 77.026352
Parking 4 28.590606, 77.062959

To add these data we can execute the following query for each document:

POST parking_locations/_doc
{
"name": "Parking 1",
"location": "28.594817, 77.046608",
"address": "street 1, sec abc"
}

After executing the above command we can get the following response:

{
"_index" : "parking_locations",
"_type" : "_doc",
"_id" : "uDz1HnIBtlnNM0yOpqq6",
"_version" : 1,
"result" : "created",
"_shards" : {
"total" : 2,
"successful" : 1,
"failed" : 0
},
"_seq_no" : 0,
"_primary_term" : 1
}

We can follow the same for the other three documents we can also use bulk indexing to add all of these documents in a single query. Now we have an index with four different parking locations. To verify if all documents are added we can run the following command:

GET parking_locations/_search

The above command will list all documents of the parking_locations index and we can verify if all four documents are created in the index. So now our index is all set for a geo query. Now assume that I am a new user in the city with a current location as 28.580116, 77.051673. I am searching for a parking location to park my car so how will I get the nearest parking address?

Let us take an example where I want to search all parking located within a range of 2 KM from my current location. So to get the parking location within 2 KM range we need to execute the following query:

GET parking_locations/_search
{
"query": {
"bool" : {
"must" : {
"match_all" : {}
},
"filter" : {
"geo_distance" : {
"distance" : "2km",
"location" : "28.580116, 77.051673"
}
}
}
}
}

After executing the following command we can see that there are three parking locations within 2 KM from my location. Please refer to the following response which we can receive after executing the above query:

{
"took" : 8,
"timed_out" : false,
"_shards" : {
"total" : 1,
"successful" : 1,
"skipped" : 0,
"failed" : 0
},
"hits" : {
"total" : {
"value" : 3,
"relation" : "eq"
},
"max_score" : 1.0,
"hits" : [
{
"_index" : "parking_locations",
"_type" : "_doc",
"_id" : "uDz1HnIBtlnNM0yOpqq6",
"_score" : 1.0,
"_source" : {
"name" : "Parking 1",
"location" : "28.594817, 77.046608",
"address" : "street 1, sec abc"
}
},
{
"_index" : "parking_locations",
"_type" : "_doc",
"_id" : "uTz3HnIBtlnNM0yOj6qg",
"_score" : 1.0,
"_source" : {
"name" : "Parking 2",
"location" : "28.593168, 77.041244",
"address" : "street 3, sec wer"
}
},
{
"_index" : "parking_locations",
"_type" : "_doc",
"_id" : "uzz3HnIBtlnNM0yO_aou",
"_score" : 1.0,
"_source" : {
"name" : "Parking 4",
"location" : "28.590606, 77.062959",
"address" : "street 4, sec qer"
}
}
]
}
}

In this way, we can fetch the documents having geolocation from our current location by providing different distance range. We can change this 2 KM range to any other range and can get a different set of documents.

In case of any doubt please leave your comments. You can also follow me on:
Twitter: https://twitter.com/anu4udilse
LinkedIn: https://www.linkedin.com/in/anubioinfo
Medium: https://anubioinfo.medium.com

If you found this article interesting, then you can explore “Mastering Kibana 6.0”, “Kibana 7 Quick Start Guide”, “Learning Kibana 7”, and “Elasticsearch 7 Quick Start Guide” books to get more insight about Elastic Stack, how to perform data analysis, and how you can create dashboards for key performance indicators using Kibana

--

--

Author of “Mastering Kibana6.x”, “Kibana7 Quick Start Guide”, “Learning Kibana7”, &“Elasticsearch7 Quick Start Guide” books & AWS Certified Solutions Architect.