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

后端 未结 1 860
清酒与你
清酒与你 2020-12-30 15:23

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 coordina

相关标签:
1条回答
  • 2020-12-30 15:58

    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": []
    }
    
    0 讨论(0)
提交回复
热议问题