2

I have indexed a number of documents in my Elasticsearch database and when I query for all them I see they have a structure like this:

GET http://localhost:9200/restaurants/restaurant/_search

Output:

{
    "took": 4,
    "timed_out": false,
    "_shards": {
        "total": 5,
        "successful": 5,
        "failed": 0
    },
    "hits": {
        "total": 362,
        "max_score": 1,
        "hits": [
            {
                "_index": "restaurants",
                "_type": "restaurant",
                "_id": "2",
                "_score": 1,
                "_source": {
                    "businessName": "VeeTooNdoor Dine",
                    "geoDescription": "Right next to you2",
                    "tags": {},
                    "location": {
                        "lat": -33.8917007446,
                        "lon": 151.1369934082
                    }
                }
            },
            ...
         ]
     }
}

I now want to search for restaurants around a given geo-location and following the documentation [1] I use something like this:

{
    "filtered" : {
        "query" : {
            "match_all" : {}
        },
        "filter" : {
            "geo_distance" : {
                "distance" : "1km",
                "location" : {
                    "lat": -33.8917007446,
                    "lon": 151.1369934082
                }
            }
        }
    }
}

The thing I have changed is the match_all since I don't want to specify any search field in particular, I only care about the geo location.

When I run the query I get the following message:

"error": "SearchPhaseExecutionException[Failed to execute phase [query], all shards failed; shardFailures {[olAoWBSJSF2XfTnzEhKIYA][btq][3]: SearchParseException[[btq][3]: from[-1],size[-1]: Parse Failure [Failed to parse source [{\n    \"filtered\" : {\n        \"query\" : {\n            \"match_all\" : {}\n        },\n        \"filter\" : {\n  .....       

Now I did notice the following on the tutorial page:

Update: The automatic mapping of “geo enabled” properties has been disabled since publishing this article. You have to provide the correct mapping for geo properties. Please see the documentation.

Which gives me the impression that I have to create a "mapping" which specifies the field types. However, in the document it refers to doesn't give me enough information on how to actually do this. It shows blobs of JSON but I'm not sure about the correct URL's for this.

Further more, I'm using the PHP client and I'm not sure if it even supports mappings as is demonstrated in this walk through [2].

I somehow get the impression that quite a bit of changes have been made to the query DSL etc. and that a lot of examples on the web don't work anymore, I could be wrong through. I'm using Elasticsearch 1.0.0.

[1] http://www.elasticsearch.org/blog/geo-location-and-search

[2] http://blog.qbox.io/elasticsearch-aggregations

Luke
  • 20,878
  • 35
  • 119
  • 178

4 Answers4

3

Things that might be wrong:
1: your query shows pin.location and your field is just location.
2: your _mapping for location could be wrong

Does your mapping show something like:

"location": {
    "type": "geo_point",
    "geohash_precision": 4
 }

I was able to run this search against some of my own data:

POST /myindex/mydata/_search
{
     "query": {
         "match_all": {}
     },
     "filter": {
            "geo_distance" : {
                "distance" : "100km",
                "_latlng_geo" : {
                    "lat": -33.8917007446,
                    "lon": 151.1369934082
                }
            }     
     }
}

... a snippet of my mapping:

     "properties": { .....
        "_latlng_geo": {
           "type": "geo_point",
           "geohash_precision": 4
        }
        .....

EDIT : How to use Put Mapping API

You can create the mapping when you create the index like so:

PUT /twitter/
{
"settings" : {
    "number_of_shards" : 1
},
"mappings" : {
    "tweet":{
    "properties":{
        "latlng" : {
            "type" : "geo_point"
        }
    }
    }
  }
}
mconlin
  • 8,169
  • 5
  • 31
  • 37
  • Hi. Thanks for that. The "pin" in the code example was a copy mistake, I removed it, its not there in my actual code. I think what you say about the mapping not being there to be correct. However, I have no idea on how to actually create a mapping, either from cURL or the PHP API client. Could you elaborate on that? Also, what version of Elasticsearch are you using? – Luke Feb 17 '14 at 22:02
3

removing the query is what finally worked for me:

{
"filter": {
    "geo_distance" : {
            "distance" : "300km",
            "location" : {
                "lat" : 45,
                "lon" : -122
            }
        }  
    }
}
dwenaus
  • 3,206
  • 2
  • 27
  • 27
1

You have to replace "location" by "restaurant.location" because ElasticSearch interprete it like a type not like a attribute.

 {
    "filtered" : {
        "query" : {
            "match_all" : {}
        },
        "filter" : {
            "geo_distance" : {
                "distance" : "1km",
                "restaurant.location" : {
                    "lat": -33.8917007446,
                    "lon": 151.1369934082
                }
            }
        }
    }

I hope it helps you.

Sapikelio
  • 2,594
  • 2
  • 16
  • 40
0

As stated in the docs:

"We use the generic PHP stdClass object to represent an empty object. The JSON will now encode correctly."

http://www.elasticsearch.org/guide/en/elasticsearch/client/php-api/current/_dealing_with_json_arrays_and_objects_in_php.html

In your case you should use

$searchParams['body']['query']['filtered']['query']['match_all'] = new \stdClass();
Chau Thai
  • 313
  • 3
  • 14