Elasticsearch and GEO query – Geo Point Type

Elasticsearch has become an extremely popular search engine but … as so often … documentation could be improved still quite a bit. Find below a short tutorial on how to identify (map) a field as geo_point field and FYI, the official Elasticsearch documentation is far from clear (and correct) with regards to this topic. Apparently, this mapping was done, by Elasticsearch, implicitly in the past but in version 1.4.1 this has to be done explicitly.

Functionality

The functionality we will support is extremely straightforward. We manage a number of employees and we’ll persist name, address and location (identified by latitude and longitude). Our GEO query will simply return the employees living closer than a certain distance from our office.

Mapping

Mapping and identifying our location field as a geo_point is to first thing to be done. This can be easily done with the below command. FYI, our index is named employees and our index-type is employee.

PUT http://localhost:9200/employees
{
    "mappings": {
        "employee": {
            "properties": {
                "location": {"type": "geo_point"}
            }
        }
    }
}

Creating Employees

Creating employees can be done with following command (this example creates employee with identifier 3). No surprises here.

PUT http://localhost:9200/employees/employee/3
{
	"officeAddress":"Tweebunder 4",
	"officeCity":"Edegem",
	"officeCountry":"België",
	"employeeAddress":"Solvynsstraat",
	"employeeCity":"Antwerpen",
	"employeeCountry":"België",
	"location" : {
		"lat" : 51.2061132,
		"lon" : 4.4011606
	} 	
}

You’ll notice we only defined one type explicitly but if you retrieve the metadata you’ll notice all fields have been mapped implicitly by Elasticsearch afterwards:

elasticsearch mapping

And as expected, our first spatial retrieves the employees living less than 10 kilometers from the office:

POST http://localhost:9200/employees/employee/_search
  "query": {
    "filtered": {
      "filter": {
        "geo_distance": {
          "location": {
            "lat": 51.150054,
            "lon": 4.458196
          },
          "distance": "10km"
        }
      }
    }
  }
}

And by using elasticsearch aggregations, one can spice up the logic of the spatial queries a little. This query counts the number of employees living within a certain range from the office.

POST http://localhost:9200/employees/employee/_search
{
   "size": 0,
   "aggregations": {
      "employees_close_to_office": {
         "geo_distance": {
            "field": "location",
            "origin": "51.150054, 4.458196",
            "unit": "km",
            "ranges": [
               {
                  "from": 0,
                  "to": 10
               }
            ]
         }
      }
   }
}

{
   "took": 1,
   "timed_out": false,
   "_shards": {
      "total": 5,
      "successful": 5,
      "failed": 0
   },
   "hits": {
      "total": 5,
      "max_score": 0,
      "hits": []
   },
   "aggregations": {
      "employees_close_to_office": {
         "buckets": [
            {
               "key": "*-10.0",
               "from": 0,
               "to": 10,
               "doc_count": 2
            }
         ]
      }
   }
}

Conclusions

Elasticsearch clearly supports a plethora of search functions. Whether this ‘latest and greatest’ framework will replace partially or completely the industry standard DBMS is still to be seen. As always, don’t hesitate to ask any question or to suggest potential improvements.

 

Keywords:  Spatial Search ElasticSearch, ElasticSearch geospatial, ElasticSearch distance, ElasticSearch geo_point, geo_distance. 

 

Advertisements

About IctDynamic.Be

IctDynamic designs and develops affordable software applications for the SME We focus on • Java Freelance missions • GIS and geographical solutions • Freelance missions as project manager (certified), analyst, architect, software engineer
This entry was posted in GIS, Java, Technical and tagged , . Bookmark the permalink.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s