# Geospatial implementation

**URL:** https://discuss.elastic.co/t/geospatial-implementation/5369
**Category:** Elasticsearch
**Created:** [September 13, 2011, 9:31am UTC](https://discuss.elastic.co/t/geospatial-implementation/5369 "2011-09-13T09:31:32Z")
**Posts on this page:** 15
**Page:** 1

<div class="post-metadata">

### Author: ![Josh\_Devins](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/josh_devins/32/2733_2.png) [@Josh\_Devins](https://discuss.elastic.co/u/Josh_Devins)
#### Post date: [September 13, 2011, 9:31am UTC](https://discuss.elastic.co/t/geospatial-implementation/5369/1 "2011-09-13T09:31:32Z")

</div>

I've had a quick troll through the source on GitHub and found the code  
for the GeoDistanceFilter but my familiarity with Lucene innards is  
poor. My main concern is with large geo datasets in ES and how  
performant that might be (or not). At a high level, how are the  
geospatial filters implemented? Most specifically I'm interested in  
the geo\_distance and geo\_distance\_range filters.

Thanks,

Josh

---

<div class="post-metadata">

### Author: ![kimchy](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/kimchy/32/44952_2.png) [@kimchy](https://discuss.elastic.co/u/kimchy)
#### Post date: [September 13, 2011, 10:08am UTC](https://discuss.elastic.co/t/geospatial-implementation/5369/2 "2011-09-13T10:08:30Z")

</div>

Geo distance checks are done by loading all the geo points for the specific  
field to memory, and doing in memory distance checks for all the documents  
that matched your "main query". This means that with more results matching  
the query, the more computational heavy it will become.

On Tue, Sep 13, 2011 at 12:31 PM, Josh Devins [info@joshdevins.net](mailto:info@joshdevins.net) wrote:

> I've had a quick troll through the source on GitHub and found the code  
> for the GeoDistanceFilter but my familiarity with Lucene innards is  
> poor. My main concern is with large geo datasets in ES and how  
> performant that might be (or not). At a high level, how are the  
> geospatial filters implemented? Most specifically I'm interested in  
> the geo\_distance and geo\_distance\_range filters.
> 
> Thanks,
> 
> Josh

---

<div class="post-metadata">

### Author: ![Josh\_Devins](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/josh_devins/32/2733_2.png) [@Josh\_Devins](https://discuss.elastic.co/u/Josh_Devins)
#### Post date: [September 13, 2011, 10:16am UTC](https://discuss.elastic.co/t/geospatial-implementation/5369/3 "2011-09-13T10:16:37Z")

</div>

So where there is no "main query", we essentially load up all  
documents' geo points into memory and filter/do distance checks after  
the real Lucene query has been fired. Take for example the following  
query, which I assume because of "match\_all" acts as described above.

```
"filtered": {
    "query": {
        "match_all": {}
    },
    "filter": {
        "geo_distance": {
            "distance": "5km",
            "place.location": {
                "lat": 10,
                "lon": 70
            }
        }
    }
}
```

---

<div class="post-metadata">

### Author: ![kimchy](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/kimchy/32/44952_2.png) [@kimchy](https://discuss.elastic.co/u/kimchy)
#### Post date: [September 13, 2011, 10:21am UTC](https://discuss.elastic.co/t/geospatial-implementation/5369/4 "2011-09-13T10:21:43Z")

</div>

All field values are loaded into memory and persisted there, regardless of  
the query. And yes, on a match all query, it will be (in memory) checked  
against all docs. In master, this will be faster (for distance) since it  
will do bounding box checks first.

On Tue, Sep 13, 2011 at 1:16 PM, Josh Devins [info@joshdevins.net](mailto:info@joshdevins.net) wrote:

> So where there is no "main query", we essentially load up all  
> documents' geo points into memory and filter/do distance checks after  
> the real Lucene query has been fired. Take for example the following  
> query, which I assume because of "match\_all" acts as described above.
> 
> "filtered": {  
> "query": {  
> "match\_all": {}  
> },  
> "filter": {  
> "geo\_distance": {  
> "distance": "5km",  
> "place.location": {  
> "lat": 10,  
> "lon": 70  
> }  
> }  
> }  
> }

---

<div class="post-metadata">

### Author: ![Josh\_Devins](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/josh_devins/32/2733_2.png) [@Josh\_Devins](https://discuss.elastic.co/u/Josh_Devins)
#### Post date: [September 13, 2011, 10:41am UTC](https://discuss.elastic.co/t/geospatial-implementation/5369/5 "2011-09-13T10:41:29Z")

</div>

Great to know about the bounding-box checking on master. I was going  
to just add a geohash that can be part of the main query to filter the  
list down before going into memory and doing the distance checks. I  
assume this would have the same/similar effect as what's on master?

---

<div class="post-metadata">

### Author: ![kimchy](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/kimchy/32/44952_2.png) [@kimchy](https://discuss.elastic.co/u/kimchy)
#### Post date: [September 13, 2011, 12:07pm UTC](https://discuss.elastic.co/t/geospatial-implementation/5369/6 "2011-09-13T12:07:29Z")

</div>

The bounding box check is also done in memory, how were you thinking of  
adding the geo hash based check? Using a term query / filter?

On Tue, Sep 13, 2011 at 1:41 PM, Josh Devins [info@joshdevins.net](mailto:info@joshdevins.net) wrote:

> Great to know about the bounding-box checking on master. I was going  
> to just add a geohash that can be part of the main query to filter the  
> list down before going into memory and doing the distance checks. I  
> assume this would have the same/similar effect as what's on master?

---

<div class="post-metadata">

### Author: ![Josh\_Devins](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/josh_devins/32/2733_2.png) [@Josh\_Devins](https://discuss.elastic.co/u/Josh_Devins)
#### Post date: [September 13, 2011, 12:24pm UTC](https://discuss.elastic.co/t/geospatial-implementation/5369/7 "2011-09-13T12:24:34Z")

</div>

I haven't played with it yet, but probably with a term query. This  
should then return at least a subset of results rather than the entire  
corpus, that need to be dealt with in memory. The geohash in the query  
would be much shorter than the high-precision geohash derived from the  
lat/lon stored in the index/with the document. This is basically a  
bounding box search using Lucene to do the heavy lifting first.

At least, that was the plan! Happy to hear your thoughts.

---

<div class="post-metadata">

### Author: ![Josh\_Devins](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/josh_devins/32/2733_2.png) [@Josh\_Devins](https://discuss.elastic.co/u/Josh_Devins)
#### Post date: [September 13, 2011, 2:18pm UTC](https://discuss.elastic.co/t/geospatial-implementation/5369/8 "2011-09-13T14:18:17Z")

</div>

On second thought, I think geohash might be more than necessary. You  
mention that what is in master right now relies on first doing a  
bounding box filter, then the range filter. Why not use a range query  
on the minimum bounding box of the geo\_distance radius to narrow this  
down in Lucene first, then what you have in memory you can just apply  
the regular geo\_distance filter? Not sure about performance, but it  
would then not require a pre-calculated geohash in the index.

---

<div class="post-metadata">

### Author: ![kimchy](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/kimchy/32/44952_2.png) [@kimchy](https://discuss.elastic.co/u/kimchy)
#### Post date: [September 13, 2011, 8:26pm UTC](https://discuss.elastic.co/t/geospatial-implementation/5369/9 "2011-09-13T20:26:02Z")

</div>

We can definitely do that, its actually something that I want to do (once we  
can derive the bounding box from the distance). Its the same question  
between "range" filter and "numeric\_range" filter. The first uses the index  
data to do the range check, the second does only in memory range checks.  
Some times the fist one is faster, and sometimes the second one is.

For most typical cases, where the geo functionality is driven by a main  
query that already narrows down the search, the in memory checks will be  
faster. It might even be faster in the match\_all case (depends on the  
distribution of data).

But, we can definitely have an option to do "indexed" based range checks for  
bounding box (will require also indexing the lat/lon). Note, this will not  
work with multiple locations per doc (unless nested mapping is used). Can  
you open an issue?

On Tue, Sep 13, 2011 at 5:18 PM, Josh Devins [info@joshdevins.net](mailto:info@joshdevins.net) wrote:

> On second thought, I think geohash might be more than necessary. You  
> mention that what is in master right now relies on first doing a  
> bounding box filter, then the range filter. Why not use a range query  
> on the minimum bounding box of the geo\_distance radius to narrow this  
> down in Lucene first, then what you have in memory you can just apply  
> the regular geo\_distance filter? Not sure about performance, but it  
> would then not require a pre-calculated geohash in the index.

---

<div class="post-metadata">

### Author: ![kimchy](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/kimchy/32/44952_2.png) [@kimchy](https://discuss.elastic.co/u/kimchy)
#### Post date: [September 14, 2011, 11:28am UTC](https://discuss.elastic.co/t/geospatial-implementation/5369/10 "2011-09-14T11:28:35Z")

</div>

Ok, went ahead and pushed support for using indexed lat/lon to filer geo  
locations, depending on your dataset distribution, it might prove faster:  
[Allow to filter geo bounding box or distance based on indexed lat lon · Issue #1334 · elastic/elasticsearch · GitHub](https://github.com/elasticsearch/elasticsearch/issues/1334).

On Tue, Sep 13, 2011 at 11:26 PM, Shay Banon [kimchy@gmail.com](mailto:kimchy@gmail.com) wrote:

> We can definitely do that, its actually something that I want to do (once  
> we can derive the bounding box from the distance). Its the same question  
> between "range" filter and "numeric\_range" filter. The first uses the index  
> data to do the range check, the second does only in memory range checks.  
> Some times the fist one is faster, and sometimes the second one is.
> 
> For most typical cases, where the geo functionality is driven by a main  
> query that already narrows down the search, the in memory checks will be  
> faster. It might even be faster in the match\_all case (depends on the  
> distribution of data).
> 
> But, we can definitely have an option to do "indexed" based range checks  
> for bounding box (will require also indexing the lat/lon). Note, this will  
> not work with multiple locations per doc (unless nested mapping is used).  
> Can you open an issue?
> 
> On Tue, Sep 13, 2011 at 5:18 PM, Josh Devins [info@joshdevins.net](mailto:info@joshdevins.net) wrote:
> 
> > On second thought, I think geohash might be more than necessary. You  
> > mention that what is in master right now relies on first doing a  
> > bounding box filter, then the range filter. Why not use a range query  
> > on the minimum bounding box of the geo\_distance radius to narrow this  
> > down in Lucene first, then what you have in memory you can just apply  
> > the regular geo\_distance filter? Not sure about performance, but it  
> > would then not require a pre-calculated geohash in the index.

---

<div class="post-metadata">

### Author: ![Josh\_Devins](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/josh_devins/32/2733_2.png) [@Josh\_Devins](https://discuss.elastic.co/u/Josh_Devins)
#### Post date: [September 14, 2011, 4:16pm UTC](https://discuss.elastic.co/t/geospatial-implementation/5369/11 "2011-09-14T16:16:44Z")

</div>

That's great! Will have a look soon. Thanks for the quick fix!

Josh

---

<div class="post-metadata">

### Author: ![Josh\_Devins](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/josh_devins/32/2733_2.png) [@Josh\_Devins](https://discuss.elastic.co/u/Josh_Devins)
#### Post date: [September 14, 2011, 4:29pm UTC](https://discuss.elastic.co/t/geospatial-implementation/5369/12 "2011-09-14T16:29:13Z")

</div>

That's great! Will have a look soon. Thanks for the quick fix!

Josh

---

<div class="post-metadata">

### Author: ![Dennis](https://avatars.discourse-cdn.com/v4/letter/d/e56c9b/32.png) [@Dennis](https://discuss.elastic.co/u/Dennis)
#### Post date: [March 4, 2012, 6:53pm UTC](https://discuss.elastic.co/t/geospatial-implementation/5369/13 "2012-03-04T18:53:25Z")

</div>

I'm wondering how spatial search works with EleasticSearch. This old  
contrib/plugin for early Solr worked VERY well:

[http://mail-archives.apache.org/mod\_mbox/lucene-solr-user/201012.mbox/\<AANLkTi=8poOPe1V9zJcwWbDQcYNyz4bG2U6ysa+ru=xU@mail.gmail.com\>](http://mail-archives.apache.org/mod_mbox/lucene-solr-user/201012.mbox/%3CAANLkTi=8poOPe1V9zJcwWbDQcYNyz4bG2U6ysa+ru=xU@mail.gmail.com%3E)  
[http://info.dutchworks.nl/sspcontentrequestdw.html](http://info.dutchworks.nl/sspcontentrequestdw.html)

It created dynamic fields during indexing that allowed the bounding box /  
radius searches to be VERY fast. It ran a polygonal analysis, I think,  
against the geolocation, and put the results in the dynamic fields.

On Wednesday, 14 September 2011 11:29:13 UTC-5, Josh Devins wrote:

> That's great! Will have a look soon. Thanks for the quick fix!
> 
> Josh

---

<div class="post-metadata">

### Author: ![kimchy](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/kimchy/32/44952_2.png) [@kimchy](https://discuss.elastic.co/u/kimchy)
#### Post date: [March 5, 2012, 3:11pm UTC](https://discuss.elastic.co/t/geospatial-implementation/5369/14 "2012-03-05T15:11:05Z")

</div>

I glanced over the implementation are one point, in elasticsearch, you have both available options, either do in memory bounding box checks, or indexed bounding box checks. Distance checks were always done in memory, though it optimizes the heavy distance calculation by first checking if it falls in a bounding box.

On Sunday, March 4, 2012 at 8:53 PM, Dennis wrote:

> I'm wondering how spatial search works with EleasticSearch. This old contrib/plugin for early Solr worked VERY well:
> 
> ```
> http://mail-archives.apache.org/mod_mbox/lucene-solr-user/201012.mbox/%3CAANLkTi=8poOPe1V9zJcwWbDQcYNyz4bG2U6ysa+ru=xU@mail.gmail.com%3E
> http://info.dutchworks.nl/sspcontentrequestdw.html
> 
> ```
> 
> It created dynamic fields during indexing that allowed the bounding box / radius searches to be VERY fast. It ran a polygonal analysis, I think, against the geolocation, and put the results in the dynamic fields.
> 
> On Wednesday, 14 September 2011 11:29:13 UTC-5, Josh Devins wrote:
> 
> > That's great! Will have a look soon. Thanks for the quick fix!
> > 
> > Josh

---

<div class="post-metadata">

### Author: ![system](https://us1.discourse-cdn.com/elastic/original/3X/1/a/1ac57faf039f6b580b3f104ef42a2a89e41014de.png) [@system](https://discuss.elastic.co/u/system)
#### Post date: [July 6, 2017, 3:37am UTC](https://discuss.elastic.co/t/geospatial-implementation/5369/15 "2017-07-06T03:37:21Z")

</div>


