Monday, December 2, 2013

Geo Search using Elastic Search

In this blog post, I will post some ways of performing Geo Search using Elastic Search API's.

In my Elastic Search instance, I add a few POI's. This can be done using the REST API's provided by Elastic Search. Since we need to support Geo Spatial Searching, before we insert the data, we need to create the index and also set the correct mapping.

Step 1: Create the index on which the POI's will be added.

HTTP PUT Request : http://localhost:9200/pois/

You should recieve a 200 response code confirming that the index got created.

{
ok: true
acknowledged: true
}

Step 2: Associate the correct mapping to the POI type

HTTP PUT Request : http://localhost:9200/pois/poi/_mapping

{
    "poi" :
    {
        "properties" :
        {
                "name":     {type:"string"},
                "location" :     {"type" : "geo_point"},
                "zipcode" : {"type" : "string"},
                "rating" : {"type" : "integer"}
        }
    }
}

Response:
{
ok: true
acknowledged: true

}


 


Step 3: Add the POI's into the index.

a. Create POI - Eiffel Tower
http://localhost:9200/pois/poi/1

{
    "poi" :
    {
        "location" :
        {
            "lat" : 48.858221,
            "lon" : 2.294553
        },
        "name" : "Eiffel Tower",
        "rating" : "5",
        "id" : "1",
        "city" : "Paris",
        "zipcode" : "75007"
    }
}


{
ok: true
_index: "pois"
_type: "poi"
_id: "1"
_version: 1
}


http://localhost:9200/pois/poi/2

{
    "poi" :
    {
        "location" :
        {
            "lat" : 41.889947,
            "lon" : 12.492718
        },
        "name" : "Piazza del Colosseo",
        "rating" : "5",
        "id" : "2",
        "city" : "Rome",
        "zipcode" : "00184"
    }
}


http://localhost:9200/pois/poi/3

{
    "poi" :
    {
        "location" :
        {
            "lat" : 48.870643,
            "lon" : 2.77531
        },
        "name" : "Disney Land Paris",
        "rating" : "5",
        "id" : "3",
        "city" : "Paris",
        "zipcode" : "77700"
    }
}



http://localhost:9200/pois/poi/4

{
    "poi" :
    {
        "location" :
        {
            "lat" : 40.689766,
            "lon" : -74.045688
        },
        "name" : "Statue of Liberty",
        "rating" : "5",
        "id" : "4",
        "city" : "Newyork",
        "zipcode" : "10004"
    }
}

Step 4: Now the actual search


a. Search within a specific distance from a centre (Details - http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/query-dsl-geo-distance-filter.html )
Find all the POI's within 1200 KM from  the Location identified by  47,2.29.

b. Search with in a Range from the center (Details - http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/query-dsl-geo-distance-range-filter.html)

Find all POI's within 300KM and 1200KM from the Location identified by  47,2.29.

http://localhost:9200/pois/_search?pretty=true

The Sort block in the below request is added to know the actual distance from the queried location.

{

"sort" :
    [
        {
            "_geo_distance" : {
            "poi.location" : {
                "lat" : 47,
                "lon" : 2.29
            },
            "order" : "asc",
            "unit" : "km"
            }
        }
        ],
    "query" :
    {
        "filtered" :
        {
            "query" :
            {
                "match_all" : {}
            },
            "filter" :
            {
                "geo_distance" :
                {
                    "distance" : "1200km",
                    "poi.location" :
                    {
                        "lat" : 47,
                        "lon" : 2.29
                    }
                }
            }
        }
    }
}

The response would be :

{
took: 12
timed_out: false
_shards: 
{
total: 5
successful: 5
failed: 0
}
-
hits: 
{
total: 3
max_score: null
hits: 
[
3]
0:  
{
_index: "pois"
_type: "poi"
_id: "1"
_score: null
_source: 
{
poi: 
{
location: 
{
lat: 48.858221
lon: 2.294553
}
-
name: "Eiffel Tower"
rating: "5"
id: "1"
city: "Paris"
zipcode: "75007"
}
-
}
-
sort: 
[
1]
0:  206.85649416123124
-
}
-
1:  
{
_index: "pois"
_type: "poi"
_id: "3"
_score: null
_source: 
{
poi: 
{
location: 
{
lat: 48.870643
lon: 2.77531
}
-
name: "Disney Land Paris"
rating: "5"
id: "3"
city: "Paris"
zipcode: "77700"
}
-
}
-
sort: 
[
1]
0:  211.35988347521229
-
}
-
2:  
{
_index: "pois"
_type: "poi"
_id: "2"
_score: null
_source: 
{
poi: 
{
location: 
{
lat: 41.889947
lon: 12.492718
}
-
name: "Piazza del Colosseo"
rating: "5"
id: "2"
city: "Rome"
zipcode: "00184"
}
-
}
-
sort: 
[
1]
0:  989.1985535877029
-
}
-
-
}
-
}