如何知道地理坐标是否位于elasticsearch中的地理多边形内?

时间:2015-04-03 06:14:13

标签: lucene elasticsearch

我正在使用弹性搜索1.4.1 - 1.4.4。我试图将地理多边形形状(文档)索引到我的索引中,现在当形状被索引时,我想知道地理坐标是否位于该特定索引地理多边形形状的边界内。

GET /city/_search
{
"query":{
    "filtered" : {
        "query" : {
            "match_all" : {}
        },
        "filter" : {
            "geo_polygon" : {
                "location" : {
                    "points" : [
                        [72.776491, 19.259634],
                        [72.955705, 19.268060],
                        [72.945406, 19.189611],
                        [72.987291, 19.169507],
                        [72.963945, 19.069596],
                        [72.914506, 18.994300],
                        [72.873994, 19.007933],
                        [72.817689, 18.896882],
                        [72.816316, 18.941052],
                        [72.816316, 19.113720],
                        [72.816316, 19.113720],
                        [72.790224, 19.192205],
                        [72.776491, 19.259634]
                    ]
                }
            }
        }
    }
}
}

使用上面的地理多边形过滤器,我可以获得所有索引的地理坐标位于所描述的多边形内,但我还需要知道非索引的地理坐标是否位于此地理多边形中。我怀疑的是,如果在弹性搜索1.4.1中有可能。

1 个答案:

答案 0 :(得分:4)

是的,过滤器可以用来解决这个问题。

与Elasticsearch的正常使用情况一样,我们将文档索引到elasticsearch,然后我们对索引数据运行查询以检索匹配/需要的文档。

但是,过滤器的工作方式不同。

在过滤器中,您可以注册查询,然后通过已注册的查询填写文档,并获取与您的文档相匹配的查询。

经历了无数的谷歌搜索结果和许多博客后,我无法找到任何可以解释我如何使用过滤器来解决这个问题的事情。

所以我用一个例子来解释这个问题,以便面临同样问题的其他人可以从我的问题和我找到的解决方案中得到一些暗示。我想如果有人可以改进我的答案,或者可以分享更好的方法。

例如: -

首先,我们需要创建一个索引。

PUT /city/

然后,我们需要为用户文档添加一个由用户组成的映射 纬度 - 经度,用于渗透已注册的查询。

PUT /city/user/_mapping
{
    "user" : {
        "properties" : {
            "location" : {
                "type" : "geo_point"
            }
        }
    }
}

现在,我们可以将我们的地理多边形查询注册为过滤器,其ID为城市名称或您想要的任何其他标识符。

PUT /city/.percolator/mumbai
{
    "query":{
        "filtered" : {
            "query" : {
                "match_all" : {}
            },
            "filter" : {
                "geo_polygon" : {
                    "location" : {
                        "points" : [
                            [72.776491, 19.259634],
                            [72.955705, 19.268060],
                            [72.945406, 19.189611],
                            [72.987291, 19.169507],
                            [72.963945, 19.069596],
                            [72.914506, 18.994300],
                            [72.873994, 19.007933],
                            [72.817689, 18.896882],
                            [72.816316, 18.941052],
                            [72.816316, 19.113720],
                            [72.816316, 19.113720],
                            [72.790224, 19.192205],
                            [72.776491, 19.259634]
                        ]
                    }
                }
            }
        }
    }
}

让我们为另一个城市注册另一个地理多边形过滤器

PUT /city/.percolator/delhi
{
    "query":{
        "filtered" : {
            "query" : {
                "match_all" : {}
            },
            "filter" : {
                "geo_polygon" : {
                    "location" : {
                        "points" : [
                            [76.846998, 28.865160],
                            [77.274092, 28.841104],
                            [77.282331, 28.753252],
                            [77.482832, 28.596619],
                            [77.131269, 28.395064],
                            [76.846998, 28.865160]
                        ]
                    }
                }
            }
        }
    }
}

现在我们已经注册了2个作为过滤器的查询,我们可以确保通过此API调用。

GET /city/.percolator/_count

现在要知道任何已注册城市是否存在地理位置,我们可以使用以下查询来填充用户文档。

GET /city/user/_percolate
{
  "doc": {
        "location" : {
            "lat" : 19.088415,
            "lon" : 72.871248
             }
          }
}

这将返回:_id as" mumbai"

{
   "took": 25,
   "_shards": {
      "total": 5,
      "successful": 5,
      "failed": 0
   },
   "total": 1,
   "matches": [
      {
         "_index": "city",
         "_id": "mumbai"
      }
   ]
}

尝试使用不同的lat-lon

进行另一次查询
GET /city/user/_percolate
{
  "doc": {
        "location" : {
            "lat" : 28.539933,
            "lon" : 77.331770
             }
          }
    }

这将返回:_id as" delhi"

{
   "took": 25,
   "_shards": {
      "total": 5,
      "successful": 5,
      "failed": 0
   },
   "total": 1,
   "matches": [
      {
         "_index": "city",
         "_id": "delhi"
      }
   ]
}

让我们使用随机lat-lon

运行另一个查询
GET /city/user/_percolate
{
  "doc": {
        "location" : {
            "lat" : 18.539933,
            "lon" : 45.331770
             }
          }
}

并且此查询将不返回任何匹配的结果。

{
   "took": 5,
   "_shards": {
      "total": 5,
      "successful": 5,
      "failed": 0
   },
   "total": 0,
   "matches": []
}