How to know if a geo coordinate lies within a geo polygon in elasticsearch?

北战南征 提交于 2019-12-18 13:38:26

问题


I am using elastic search 1.4.1 - 1.4.4. I'm trying to index a geo polygon shape (document) into my index and now when the shape is indexed i want to know if a geo coordinate lies within the boundaries of that particular indexed geo-polygon shape.

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]
                    ]
                }
            }
        }
    }
}
}

With above geo polygon filter i'm able get all indexed geo-coordinates lies within described polygon but i also need to know if a non-indexed geo-coordinate lies with in this geo polygon or not. My doubt is that if that is possible in the elastic search 1.4.1.


回答1:


Yes, Percolator can be used to solve this problem.

As in normal use case of Elasticsearch, we index our docs into elasticsearch and then we run queries on indexed data to retrieve matched/ required documents.

But percolators works in a different way of it.

In percolators you register your queries and then you percolate your documents through registered queries and gets back the queries which matches your documents.

After going through infinite number of google results and many of blogs i wasn't able to find any thing which could explain how i can use percolators to solve this problem.

So i'm explaining this with an example so that other people facing same problem can take a hint from my problem and the solution i found. I would like if someone can improve my answer or can share a better approach of doing it.

e.g:-

First of all we need to create an index.

PUT /city/

then, we need to add a mapping for user document which consist a user's latitude-longitude for percolating against registered queries.

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

Now, we can register our geo polygon queries as percolators with id as city name or any other identifier you want to.

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]
                        ]
                    }
                }
            }
        }
    }
}

Let's register another geo polygon filter for another city

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]
                        ]
                    }
                }
            }
        }
    }
}

Now we have registered 2 queries as percolators and we can make sure by making this API call.

GET /city/.percolator/_count

Now to know if a geo point exist with any of registered cities we can percolate a user document using below query.

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

This will return : _id as "mumbai"

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

trying another query with different lat-lon

GET /city/user/_percolate
{
  "doc": {
        "location" : {
            "lat" : 28.539933,
            "lon" : 77.331770
             }
          }
    }

This will return : _id as "delhi"

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

Let's run another query with random lat-lon

GET /city/user/_percolate
{
  "doc": {
        "location" : {
            "lat" : 18.539933,
            "lon" : 45.331770
             }
          }
}

and this query will return no matched results.

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


来源:https://stackoverflow.com/questions/29427121/how-to-know-if-a-geo-coordinate-lies-within-a-geo-polygon-in-elasticsearch

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!