Elasticsearch Geo-point queries with Elassandra and Scala
Happy searchOps
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
- http://www.elasticsearchtutorial.com/spatial-search-tutorial.html
- https://ictcalimero.wordpress.com/2014/12/14/elasticsearch-and-geo-query-geo_point/
- https://medium.com/rahasak/elasticsearch-scala-client-7c075935e8f7
- https://qbox.io/blog/tutorial-how-to-geolocation-elasticsearch
- https://medium.com/rahasak/elassandra-936ab46a6516