2014-05-14 36 views
1

我有一个用例,其中我有2种类型的位置条件的查询(即,具有geo_point型):为地理位置查找

  1. 位置1:具有纬度/经度与说半径= 90英里(它将会发生变化)和类型=传出
  2. 位置2:具有纬度/经度,没有半径和类型=传入现在

,当查询与进来:纬度/经度和半径= 20,我期望这发生:

  1. 简单的地理位置查询:如果输入纬度/经度位于位置2的20miles内,则返回位置2.
  2. 如果输入纬度/经度位于位置1的90英里内,则返回位置1。如果您注意到,我希望输入半径被特定类型位置的保存半径覆盖。

这是我想出了利用脚本:

{ 
    "query": { 
    "match_all": {} 
    }, 
    "filter": { 
    "script": { 
     "script": "!doc['geopoint'].empty && doc['coverage_type'].value == 'outgoing' ? doc['geopoint'].distanceInMiles(37,-121) <= doc['radius'].value : doc['geopoint'].distanceInMiles(37,-121) <= 20" 
    } 
    } 
} 

其中“37,-121”是经/纬度和20的输入是输入半径。

您对查询有什么看法,这是做这件事的最好方法吗?

最初发布this on ES mailing list,没有运气。

回答

2

这对我来说似乎没问题。另一种更详细的方法是将脚本分解为各种ES过滤器,以便ES尽可能优化您的请求(您可以针对您的某个案例使用特定的geo_distance过滤器)。 例如,你可以有这样的事情:(抱歉,如果JSON是不完全一样,我没有办法,现在对其进行测试)

{ 
    "query": { 
    "match_all": {} 
    }, 
    "filter": { 
    "bool": { 
     "should": [ 
      { 
       "and": [ 
        { 
         "term": { 
          "coverage_type": "outgoing" 
         } 
        }, 
        { 
         "script": { 
          "script": "!doc['geopoint'].empty && doc['geopoint'].distanceInMiles(37,-121) <= doc['radius'].value" 
         } 
        } 
       ] 
      }, 
      { 
       "and": [ 
        { 
         "term": { 
          "coverage_type": "incoming" 
         } 
        }, 
        { 
         "geo_distance" : { 
          "geopoint" : [ 37, -121 ], 
          "distance" : "20km" 
         } 
        } 
       ] 
      } 
     ] 
    } 
    } 
} 

您可能需要添加一些特定的过滤器来管理的事实您的文档中可能缺少一个地理点,并且您想如何处理这个问题。例如,您可能希望允许一个人在没有地理位置的情况下获取所有文档,在这种情况下,您可以向“应该”添加“缺失”过滤器。我希望有所帮助。