Unexpected behavior with Elasticsearch GeoShape query

(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.

Figured it out mostly. The above code has a typo in the mapping where the doc type is 'metro' but everywhere else I use DOC_TYPE of 'metros'.

But contains still returns an error.

1 Like