Elasticsearch Geo-point queries with Elassandra and Scala

Happy searchOps

(λx.x)eranga
Effectz.AI
3 min readFeb 17, 2020

--

Background

Location data can be saved in Elasticsearch as latitude-longitude pair with geo_point data type. geo_point can be used to determine the distance to another point, whether the point falls into a well-known square etc. In this post I’m gonna discuss about using Elasticsearch geo_point queries with Scala application. In my previous post I have discussed about using basic Elasticsearch queries(term, wildcard, nested, range) with Scala application. All the source codes which related to this post available in gitlab.

Run elasticsearch

I have run Elasticsearch with Elassandra docker image. Elassandra built by combining Elasticseach with Cassandra. It comes Elasticsearch as a Cassandra plugin. Basically it has Cassandra API as well as Elasticsearch API. When data save on Cassandra it will automatically index on Elasticsearch. Read more about Elassandra from here. Following is the docker-compose.yml to run the elassandra.

Sbt dependency

To build Elasticsearch Scala client, first I need to define Elasticsearch client library dependency on build.sbt file in Scala sbt application. Following is the build.sbt file with Elasticsearch dependency.

Elasticsearch index

Elassandra provide automatically create Elasticsearch indexes form Cassandra table schemas. Read more about creating Elasticsearch search index in Elassandra from here. Following are the Cassandra schemas I have used. I have a cassandra UDT named geo_point(to keeps lat, lon fields) and a table named offers. Following are the Cassandra schemas.

Following is the way to created Elasticsearch index from offers tables. When creating index I have dynamically mapped Cassandra geo_point UDT into Elasticsearch geo_point type. In here index creation also done with Scala application. When creating index it execute HTTP PUT request.

Following is the structure of the offers Elasticsearch index. It contains geo_point type fields with lat, lon fields.

Bootstrap data

I have bootstrap data into offers index by using Cassandra cqlsh API in Elassandra. When saving data in Cassandra offers table, it will automatically update the data in Elasticsearch offers index. Following are the data in offers index.

Elasticsearch config

I have defined Elasticsearch configurations(host, port, cluster info, index info, index info etc) in elastic.conf file.

Elasticsearch cluster

To create a connection to Elasticsearch cluster I have defined ElasticCluster trait. This trait can be reused in search application.

Case classe

Next I have defined Scala case class to map offers index field into JVM objects. Following is the case class.

Helper functions

I have defined helper functions to convert offers(with dates and geo_point) on Elasticsearch to Scala case class.

Geo distance query

GeoDistanceQueryBuilder provides a filter to filter data based on a specific distance from a specific geo location/point. In here I have search offers in range of 10 km from the geo point 37.9174, -122.3050.

Run queries

Following is the main application which executes these queries. It first initialize the Elasticsearch index, then execute queries to search offers.

Reference

  1. http://www.elasticsearchtutorial.com/spatial-search-tutorial.html
  2. https://ictcalimero.wordpress.com/2014/12/14/elasticsearch-and-geo-query-geo_point/
  3. https://medium.com/rahasak/elasticsearch-scala-client-7c075935e8f7
  4. https://qbox.io/blog/tutorial-how-to-geolocation-elasticsearch
  5. https://medium.com/rahasak/elassandra-936ab46a6516

--

--