ElasticSearch:跨类型的GeoLocation距离搜索

时间:2015-10-12 18:51:11

标签: search elasticsearch geolocation

如下所示,我的城市索引有两种类型 - 动物园酒店。如何找到所有在1KM半径范围内拥有酒店的动物园?这是我的索引的映射:

GET /city/_mapping
{
   "city": {
      "mappings": {
         "hotel": {
            "properties": {
               "location": {
                  "type": "geo_point"
               },
               "name": {
                  "type": "string"
               }
            }
         },
         "zoo": {
            "properties": {
               "location": {
                  "type": "geo_point"
               },
               "name": {
                  "type": "string"
               }
            }
         }
      }
   }
}

1 个答案:

答案 0 :(得分:0)

您可以使用geo-distance filter为整个索引执行此操作(只是不指定类型)。

当我快速测试时,我创建了一个这样的索引:

PUT /test_index/
{
   "mappings": {
      "hotel": {
         "properties": {
            "location": {
               "type": "geo_point"
            },
            "name": {
               "type": "string"
            }
         }
      },
      "zoo": {
         "properties": {
            "location": {
               "type": "geo_point"
            },
            "name": {
               "type": "string"
            }
         }
      }
   }
}

添加了几个文件

POST /test_index/_bulk
{"index":{"_type":"hotel","_id":1}}
{"name":"hotel1","location":{"lat" : 40.001, "lon" : -70.001}}
{"index":{"_type":"zoo","_id":1}}
{"name":"zoo1","location":{"lat" : 40.002, "lon" : -70.002}}

然后我可以像这样搜索。此查询返回一个文档:

POST /test_index/_search
{
   "query": {
      "filtered": {
         "filter": {
            "geo_distance": {
               "distance": 200,
               "distance_unit": "km",
               "location": {
                  "lat": 40,
                  "lon": -70
               }
            }
         }
      }
   }
}
...
{
   "took": 2,
   "timed_out": false,
   "_shards": {
      "total": 1,
      "successful": 1,
      "failed": 0
   },
   "hits": {
      "total": 1,
      "max_score": 1,
      "hits": [
         {
            "_index": "test_index",
            "_type": "hotel",
            "_id": "1",
            "_score": 1,
            "_source": {
               "name": "hotel1",
               "location": {
                  "lat": 40.001,
                  "lon": -70.001
               }
            }
         }
      ]
   }
}

此查询同时返回:

POST /test_index/_search
{
   "query": {
      "filtered": {
         "filter": {
            "geo_distance": {
               "distance": 300,
               "distance_unit": "km",
               "location": {
                  "lat": 40,
                  "lon": -70
               }
            }
         }
      }
   }
}
...
{
   "took": 5,
   "timed_out": false,
   "_shards": {
      "total": 1,
      "successful": 1,
      "failed": 0
   },
   "hits": {
      "total": 2,
      "max_score": 1,
      "hits": [
         {
            "_index": "test_index",
            "_type": "hotel",
            "_id": "1",
            "_score": 1,
            "_source": {
               "name": "hotel1",
               "location": {
                  "lat": 40.001,
                  "lon": -70.001
               }
            }
         },
         {
            "_index": "test_index",
            "_type": "zoo",
            "_id": "1",
            "_score": 1,
            "_source": {
               "name": "zoo1",
               "location": {
                  "lat": 40.002,
                  "lon": -70.002
               }
            }
         }
      ]
   }
}

这是我用来测试它的代码:

http://sense.qbox.io/gist/948d23a5327cf5f22dd368146f37d09e30765fee