(copied from this stackoverflow question)
Using Elasticsearch 2.3.1 and the python client I'm getting unexpected results with geo search. In the code below I create a simple index. I then index two shapes - a big square and a small square completely contained in that square (look at them here). I then query the index using with the small square using all available strategies {'intersects', 'disjoint', 'within', 'contains'}.
from elasticsearch import Elasticsearch
es_client = Elasticsearch()
# CREATE INDEX
INDEX = "geo_shapes_2"
DOC_TYPE = "metros"
es_client.indices.delete(INDEX, ignore=404)
body = {
"mappings": {
"metro": {
"properties": {
"id": {
"type": "string",
"index": "not_analyzed"
},
"geometry": {
"type": "geo_shape",
"tree": "quadtree",
"precision": "50m",
"distance_error_pct": 0.025
}
}
}
}
}
es_client.indices.create(INDEX, body)
# INDEX TWO DOCS
# small_square is completely contained within big_square
small_square = 'small square'
body = {
'id': small_square,
'geometry': {
"type": "Polygon",
"coordinates": [
[
[
-106.248779296875,
35.12889434101051
],
[
-106.34765625,
35.88014896488361
],
[
-105.062255859375,
35.8356283888737
],
[
-105.13916015625,
35.05698043137265
],
[
-106.248779296875,
35.12889434101051
]
]
]
}
}
es_client.create(INDEX, DOC_TYPE, body=body, id=small_square)
big_square = 'big square'
body = {
'id': big_square,
'geometry': {
"type": "Polygon",
"coordinates": [
[
[
-108.97338867187499,
32.93492866908233
],
[
-108.69873046875,
38.19502155795573
],
[
-102.095947265625,
38.12591462924157
],
[
-102.39257812499999,
32.87036022808355
],
[
-108.97338867187499,
32.93492866908233
]
]
]
}
}
es_client.create(INDEX, DOC_TYPE, body=body, id=big_square)
# ISSUE ALL 4 STRATEGY QUERIES FOR SMALL SQUARE
body = {
'filter': {
'geo_shape': {
'geometry': {
'indexed_shape': {
'id': small_square,
'type': DOC_TYPE,
'index': INDEX,
'path': 'geometry',
},
}
}
}
}
for strategy in ['intersects', 'disjoint', 'within', 'contains']:
body['filter']['geo_shape']['geometry']['relation'] = strategy
response = es_client.search(INDEX, body=body)
print strategy + ': ' + (', '.join([r['_source']['id'] for r in response['hits']['hits']]) or 'none')
Here I would expect the response to be:
intersects: big square, small square
disjoint: none
within: none (or maybe include small square depending upon the semantics of "within")
contains: big square, small square (or maybe omit small square depending upon the semantics of "contains")
Instead I see:
intersects: none
disjoint: big square, small square
within: none
and this is followed by an error
...
/Library/Python/2.7/site-packages/elasticsearch/connection/base.pyc in _raise_error(self, status_code, raw_data)
106 pass
107
--> 108 raise HTTP_EXCEPTIONS.get(status_code, TransportError)(status_code, error_message, additional_info)
109
110
RequestError: TransportError(400, u'search_phase_execution_exception', u'')
Am I doing something wrong? Or is this a bug?
UPDATE: I noticed that the geometry.type can be any string - I figure I would get an error if I indexed something with an invalid type.