地理位置查找的条件查询

时间:2014-05-14 18:04:57

标签: elasticsearch

我有一个用例,我有两种类型的位置(即geo_point类型):

  1. 位置1:有一个说半径= 90英里的纬度/经度(会有所不同)和类型=传出
  2. 位置2:具有没有半径的纬度/经度且类型=传入
  3. 现在,当查询带有:lat / lon和radius = 20时,我预计会发生这种情况:

    1. 简单地理查找:如果输入纬度/经度位于位置2的20英里范围内,则返回位置2.
    2. 如果输入lat / lon在位置1的90英里范围内,则在结果中返回位置1。如果您注意到,我希望输入半径被特定类型位置的保存半径覆盖。
    3. 这是我用脚本提出的:

      {
        "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"
          }
        }
      }
      

      其中&#34; 37,-121&#34;是输入lat / lon,20是输入半径。

      您如何看待查询,这是最好的方法吗?

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

1 个答案:

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

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