GeoDistance Aggregation with the cities around a point

26 views
Skip to first unread message

Nikolay Nikolov

unread,
Feb 27, 2016, 10:04:48 AM2/27/16
to Elastica - Elasticsearch PHP Client
Hi, I am attaching a screenshot with the result, which I want to become with the new Aggregations.


When I type a City (I have the geo coords) I would like to become the cities nearby of this point with the distance to my point and amount of results.

Is this possible without to put a script to calculate the distance?

Thanks
Nik

Nikolay Nikolov

unread,
Feb 27, 2016, 11:38:08 AM2/27/16
to Elastica - Elasticsearch PHP Client
I have trying this, but something is wrong:

location is a geo_point

$termsAgg2 = new Elastica\Aggregation\Terms("location_radius");
$termsAgg2
->setField("location_name");
$termsAgg2
->setSize(10);
$termsAgg2
->setScript(new Elastica\Script\Script("ceil(doc['location'].arcDistanceInKm(51.2249429, 6.7756524))"));
$elasticaQuery
->addAggregation($termsAgg2);


My earlier implementation with Facet was in this way:


$tagFacet = new \Elastica\Facet\Terms("location_radius");



$tagFacet
->setField('location_name');
$tagFacet
->setAllTerms(true);
$tagFacet
->setSize(100);
$tagFacet
->setScript(
               
"doc['location'].empty ? null : ceil(doc['location'].arcDistanceIn".$unit."(".
                $entries
->getLocationLatitude().", ".
                $entries
->getLocationLongitude().")) + '|' + doc['location_name'].value
            + '|' + doc['location_id'].value"

           
);



Someone can help me?



If I try this script:


$termsAgg2->setScript(new Elastica\Script\Script("ceil(doc['location'].arcDistanceInKm(51.2249429, 6.7756524))+ '|' + doc['location_name'].value"));

Error in elasticsearch logs is:


Caused by: ScriptException[failed to run inline script [ceil(doc['location'].arcDistanceInKm(51.2249429, 6.7756524)) + '|' + doc['location_name'].value] using lang [groovy]]; nested: IllegalArgumentException[Negative position];


Thanks

Nik

ruflin

unread,
Feb 28, 2016, 4:50:51 AM2/28/16
to Elastica - Elasticsearch PHP Client
I didn't check it in details yet. Two thoughts:

- Do you have groovy enabled?
- As the exception points to a negative position, I assume that could be the problem?

Nikolay Nikolov

unread,
Feb 28, 2016, 11:00:52 AM2/28/16
to Elastica - Elasticsearch PHP Client
Hey, I have done it. Not perfect, maybe someone can bring this to perfection, but here is the solution:

1. The doc values can be used from fields, what are 

'index' => 'not_analyzed' 


This has cost me 1 day testing :D


2. To use this aggregations you need to remove the filed for the aggregation (0,5 days of testing), because with the new key you are generating a new one for the aggregation.


Here my solution:


$termsAgg2 = new Elastica\Aggregation\Terms("location_radius");
//$termsAgg2->setField("location_facet"); // -- removed
$termsAgg2
->setSize(20);
$termsAgg2
->setScript(new Elastica\Script\Script("doc['location'].empty ? null : ceil(doc['location'].arcDistanceInKm(51.2249429, 6.7756524)) + ' - ' + doc['location_facet'].value+ ' - ' + doc['location_id'].value"));
$elasticaQuery
->addAggregation($termsAgg2);



In ES query style this looks so:


"aggs": {
       
"location_radius": {
           
"terms": {
               
"size": 100,
               
"script": "doc['location'].empty ? null : ceil(doc['location'].arcDistanceInKm(51.2249429, 6.7756524)) + ' - ' + doc['location_facet'].value+ ' - ' + doc['location_id'].value"
           
}
       
}
   
}



Results:

"location_radius": {
         "doc_count_error_upper_bound": 0,
         "sum_other_doc_count": 0,
         "buckets": [
            {
               "key": "0.0 - Düsseldorf - 1131",
               "doc_count": 40
            },
            {
               "key": "183.0 - Frankfurt - 3183",
               "doc_count": 15
            },
            {
               "key": "487.0 - München - 2358",
               "doc_count": 14
            },

.......
           {
               "key": "5735.0 -  - 3183",
               "doc_count": 1
            },

The not perfect part ist the last result "5735.0 -  - 3183" .

In my database there are some rows, where there is no location, it is empty. And somehow the solution doc['location'].empty ? null : not works. Why? Someone some tips? 

I don't know how performant this solution is for 1M rows, but soon I will see it.

Thanks
NIk

ruflin

unread,
Feb 28, 2016, 2:20:03 PM2/28/16
to Elastica - Elasticsearch PHP Client
Glad you found a solution. As this seems to be more a Elasticsearch problem then Elastica itself, I recommend you in the future to post it in the elasticsearch forum: https://discuss.elastic.co/c/elasticsearch

Nikolay Nikolov

unread,
Mar 2, 2016, 10:36:12 AM3/2/16
to Elastica - Elasticsearch PHP Client
BTW, is this solution not possible with the GeoDistance Aggregation ?

$agg = new GeoDistance('geo', 'location', array('lat' => 32.804654, 'lon' => -117.242594));
$agg->addRange(null, 100);
$agg->setUnit('mi');

This example is delivering only the amount of data for this Distance, but is it possible to become all the cities around 100 mi radius with the amount of data?

ruflin

unread,
Mar 3, 2016, 8:25:25 AM3/3/16
to Elastica - Elasticsearch PHP Client
You mean all the cities between 90 and 110 mi? 
Reply all
Reply to author
Forward
0 new messages