Elasticsearch按位置查找文档

时间:2014-02-16 23:38:32

标签: php geolocation elasticsearch elasticsearch-1.0.0

我已在我的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  .....       

现在我在教程页面上注意到以下内容:

  

更新:已启用“已启用地理位置”属性的自动映射   自发布本文以来禁用。你必须提供   正确映射地理属性。请参阅文档。

这给我的印象是我必须创建一个指定字段类型的“映射”。但是,在它所引用的文档中并未提供有关如何实际执行此操作的足够信息。它显示了JSON的blob,但我不确定这个的正确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

4 个答案:

答案 0 :(得分: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
        }
        .....

编辑:如何使用Put Mapping API

您可以在创建索引时创建映射,如下所示:

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

答案 1 :(得分:3)

删除查询最终对我有用:

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

答案 2 :(得分:1)

您必须用" restaurant.location "替换" location" 因为ElasticSearch将其解释为类似于属性的类型。

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

我希望它可以帮到你。

答案 3 :(得分: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();