2014-02-16 4 views
2

Я индексировали ряд документов в моей базе данных Elasticsearch и когда я запрашиваю для всех них я вижу, что они имеют структуру, как это:Elasticsearch найти документы по местоположению

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

Выход:

{ 
    "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 
        } 
       } 
      }, 
      ... 
     ] 
    } 
} 

Теперь я хочу найти рестораны вокруг данного географического местоположения и следуя документации [1] Я использую что-то вроде этого:

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

Вещь, которую я изменил, это match_all, так как я не хочу указывать какое-либо поле поиска, в частности, меня интересует только географическое местоположение.

Когда я выполнить запрос, я получаю следующее сообщение:

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

Теперь я заметить следующее на странице учебника:

Обновление: автоматическое отображение «гео включено» свойств был отключен после публикации этой статьи. Вы должны предоставить правильное отображение для гео-свойств . См. Документацию.

Это создает впечатление, что мне нужно создать «сопоставление», которое задает типы полей. Однако в документе, который он ссылается, не дает мне достаточно информации о том, как это сделать на самом деле. Он показывает blobs JSON, но я не уверен в правильности URL для этого.

Кроме того, я использую PHP-клиент, и я не уверен, поддерживает ли он отображение, как это показано в этой прогулке через [2].

У меня как-то создается впечатление, что в запрос DSL и т. Д. Внесено немало изменений и что многие примеры в Интернете больше не работают, я могу ошибаться. Я использую Elasticsearch 1.0.0.

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

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

ответ

3

вещи, которые могут быть неправильно:
1: Ваш запрос показывает pin.location и ваше поле просто location.
2: ваш _mapping для location может быть неправильно

ли ваше отображение показать что-то вроде:

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

я смог запустить этот запрос против некоторых моих собственных данных:

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

...сниппет моего отображения:

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

EDIT: Как использовать Put Mapping API

Вы можете создать отображение при создании индекса, как так:

PUT /twitter/ 
{ 
"settings" : { 
    "number_of_shards" : 1 
}, 
"mappings" : { 
    "tweet":{ 
    "properties":{ 
     "latlng" : { 
      "type" : "geo_point" 
     } 
    } 
    } 
    } 
} 
+0

Hi. Спасибо за это. «Пинком» в примере кода была ошибка копирования, я удалил ее, ее не было в моем фактическом коде. Я думаю, что вы говорите о том, что отображение не является правильным. Тем не менее, я понятия не имею, как на самом деле создавать сопоставление либо из cURL, либо из клиента PHP API. Не могли бы вы рассказать об этом? Кроме того, какую версию Elasticsearch вы используете? – Luke

+0

см. Мое обновление выше – mconlin

3

удаления запроса является то, что, наконец, работал для меня:

{ 
"filter": { 
    "geo_distance" : { 
      "distance" : "300km", 
      "location" : { 
       "lat" : 45, 
       "lon" : -122 
      } 
     } 
    } 
} 
0

Как указано в документации:

«Мы используем общий объект PHP stdClass для представления пустого объекта. JSON теперь будет кодировать правильно.»

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

В вашем случае вы должны использовать

$searchParams['body']['query']['filtered']['query']['match_all'] = new \stdClass(); 
1

Вы должны заменить "местоположение" по "restaurant.location", потому что ElasticSearch интерпретируют это как тип, не похожий на атрибут.

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

Надеюсь, это вам поможет.

Смежные вопросы