How to filter based on a pair of matching geopoints within a radius?

Hi All, I am trying to match based on two geopoints (origin and destination) within a radius so that if both the query geopoints are within their respective radiuses, they will be included in the results. For instance, if the range is 100 miles from the center of New York for the origin and the range is 100 miles from the center of Miami for the destination then if my query/filter values are both in those respective ranges then they are in the result set. Make sense? Is this possible? Do you have any sample queries?

Hi @mike_mivance, Welcome to the community.

It would be helpful if you could provide some sample documents with locations and the values to filter on and the desired result. I think I understand from your description but concrete examples always help more.

Then we can see if we can build a query...

Hi @stephenb , Thank you for the welcome. We are super excited to be here. We are in the process of creating a document for this scenario and we will share it with you shortly. We appreciate any help you can provide at that point. I'm glad my description was somewhat intelligible! :slight_smile:

@mike_mivance

So here is my sample ....

It is a collection of geo_point with two keyword fields...
Notice I create the mapping first...
Then I post the documents
Then I do a search I also put these on a map...

DELETE /city

PUT /city
{
  "mappings": {
    "properties": {
      "name" : {"type" : "keyword"},
      "type" : {"type" : "keyword"},
      "location": {
        "type": "geo_point"
      }
    }
  }
}

POST /city/_doc/
{
  "name": "stamford",
  "type": "city",
  "location": [-73.554212, 41.053923]
}

POST /city/_doc
{
  "name": "greenwich",
  "type": "city",
  "location": [-74.624998,42.047451]
}

POST /city/_doc
{
  "name": "armonk",
  "type": "city",
  "location": [-75.708180,43.126757]
}

POST /city/_doc
{
  "name": "stamford",
  "type": "town",
  "location": [-75.718180,43.136757]
}

POST /city/_doc
{
  "name": "north stamford",
  "type": "city",
  "location": [-76.572866,44.142307]
}

POST /city/_doc
{
  "name": "greenwich2",
  "type": "city",
  "location": [-73.681591,41.098201]
}

POST /city/_doc
{
  "name": "rye brook",
  "type": "town",
  "location": [-73.683025,41.017221]
}

Then perform bool search with a geo_distance search with a filter for "type": "town" in 1 radius

GET /city/_search
{
  "query": {
    "bool": {
      "filter": [
        {
          "exists": {
            "field": "location"
          }
        },
        {
          "term": {
            "type": "town"
          }
        },
        {
          "geo_distance": {
            "distance": "7.71km",
            "location": [
              -75.73,
              43.0983
            ]
          }
        }
      ]
    }
  }
}

# Result

{
  "took": 1,
  "timed_out": false,
  "_shards": {
    "total": 1,
    "successful": 1,
    "skipped": 0,
    "failed": 0
  },
  "hits": {
    "total": {
      "value": 1,
      "relation": "eq"
    },
    "max_score": 0,
    "hits": [
      {
        "_index": "city",
        "_id": "Ru-N0owBsqdyNt92KLqz",
        "_score": 0,
        "_source": {
          "name": "stamford",
          "type": "town",
          "location": [
            -75.71818,
            43.136757
          ]
        }
      }
    ]
  }
}

Then, a search in another radius

GET /city/_search
{
  "query": {
    "bool": {
      "filter": [
        {
          "exists": {
            "field": "location"
          }
        },
        {
          "term": {
            "type": "town"
          }
        },
        {
          "geo_distance": {
            "distance": "7.71km",
            "location": [
              -75.73,
              43.0983
            ]
          }
        }
      ]
    }
  }
}

# Result

{
  "took": 1,
  "timed_out": false,
  "_shards": {
    "total": 1,
    "successful": 1,
    "skipped": 0,
    "failed": 0
  },
  "hits": {
    "total": {
      "value": 1,
      "relation": "eq"
    },
    "max_score": 0,
    "hits": [
      {
        "_index": "city",
        "_id": "Ru-N0owBsqdyNt92KLqz",
        "_score": 0,
        "_source": {
          "name": "stamford",
          "type": "town",
          "location": [
            -75.71818,
            43.136757
          ]
        }
      }
    ]
  }
}

Now the tricky part, and I am not sure this is exactly what you want
This filters on "type": "town"
and then the bool query should is like anOR... you have to use the should because if you do a must (AND) a point would never exist at the same time in the 2 disjoint radii.

GET /city/_search
{
  "query": {
    "bool": {
      "filter": [
        {
          "exists": {
            "field": "location"
          }
        },
        {
          "term": {
            "type": "town"
          }
        }
      ],
      "should": [
        {
          "geo_distance": {
            "distance": "13km",
            "location": [
              -73.625,
              41.049
            ]
          }
        },
        {
          "geo_distance": {
            "distance": "7.71km",
            "location": [
              -75.73,
              43.0983
            ]
          }
        }
      ]
    }
  }
}
# Result 

{
  "took": 3,
  "timed_out": false,
  "_shards": {
    "total": 1,
    "successful": 1,
    "skipped": 0,
    "failed": 0
  },
  "hits": {
    "total": {
      "value": 2,
      "relation": "eq"
    },
    "max_score": 1,
    "hits": [
      {
        "_index": "city",
        "_id": "Ru-N0owBsqdyNt92KLqz",
        "_score": 1,
        "_source": {
          "name": "stamford",
          "type": "town",
          "location": [
            -75.71818,
            43.136757
          ]
        }
      },
      {
        "_index": "city",
        "_id": "Se-N0owBsqdyNt92KLrd",
        "_score": 1,
        "_source": {
          "name": "rye brook",
          "type": "town",
          "location": [
            -73.683025,
            41.017221
          ]
        }
      }
    ]
  }
}

This is how it looks on a map BUT you can not do the should (OR) on the map...
It only supports must / AND
This picture has the radii drawn but the actual filters turned off, I did this for Visualization purposes

If you want to put the geo data on a map You need to create a data view to put the data on a map. And then use layer documents.

Thanks for this. We are working to create an example and then we can have a back and forth where you understand where we are coming from. Really appreciate the help thus far!

Hi there, sorry for the delay. This is what we were thinking:

"mappings": {
            "properties": {
                "destination": {
                    "type": "geo_point"
                },
                "name": {
                    "type": "text"
                },
                "source": {
                    "type": "geo_point"
                }
            }
        },

This topic was automatically closed 28 days after the last reply. New replies are no longer allowed.