Search code examples
pythonelasticsearchelasticsearch-dsl

Unable to locate nested geopoint after updating to elasticsearch 2.3


We use the AWS managed Elasticsearch service and recently upgraded from 1.5 to 2.3. We use the elasticsearch-dsl package in python to build our queries and managed to migrate most of our queries, but geo_distance is broken no matter what I try.

Mapping:

{
        'company': {
            'properties': {
                'id': {'type': 'integer'},
                'company_number': {'type': 'string'},
                'addresses': {
                    'type': 'nested',
                    'properties': {
                        'postcode': {'type': 'string', 'index': 'not_analyzed'},
                        'location': {'type': 'geo_point'}
                    }
                }
             }
        }
} 

Python code working with elasticsearch-dsl==0.0.11

            test_location = '53.5411062377, -2.11485504709'
            test_distance = "3miles"
            location_filter = F("geo_distance", 
                                location=test_location,
                                distance=test_distance)
            query = query.filter("nested", 
                                 path="addresses",
                                 filter=location_filter)

Query generated by the library:

{'query': {'filtered': {'filter': {'nested': {'filter': {'geo_distance': {'distance': u'3miles', 'location': '53.5411062377, -2.11485504709'}}, 'path': 'addresses'}}, 'query': {'match_all': {}}}}}

We have created a brand new index on a new 2.3 with the same mapping.

After updating to elasticsearch-dsl == 2.1.0 and attempting to convert the filters to queries:

geo_query = Q({"bool": {
                    "must": [
                        {
                            "geo_distance": {
                                "distance": "test_distance",
                                "addresses__location": test_location,
                            }
                        },
                    ]
                }})

That generates the following query:

{'query': {'bool': {'must': [{'geo_distance': {'distance': '3 miles', u'addresses.location': {'lat': '53.5411062377', 'lon': '-2.11485504709'}}}]}}}

We get the following exception:

RequestError: TransportError(400, u'search_phase_execution_exception', u'failed to find geo_point field [addresses.location]')

I tried referencing the field as 'location' , 'addresses.location', 'addresses' and using the old nested query type. I can't figure out if the mapping is no longer valid in 2.3 or if I am constructing the query wrong.

The query

Q({'nested': {'filter': {
                        'geo_distance': {'distance': u'3miles', 'location': '53.5411062377, -2.11485504709'}
                    },
                    'path': 'addresses.location'}})

Generates the following error:

RequestError: TransportError(400, u'search_phase_execution_exception', u'[nested] nested object under path [addresses.location] is not of nested type')

I think I need to add lat_lon : True to the mapping for geodistance queries to work, but none of the examples have it.

Any help would be very much appreciated, thank you!


Solution

  • This should work:

            test_location = '53.5411062377, -2.11485504709'
            test_distance = "3miles"
            location_query = Q("geo_distance", 
                                addresses__location=test_location,
                                distance=test_distance)
            query = query.filter("nested", 
                                 path="addresses",
                                 query=location_query)