Finding matches based on distance radius within documents without script


(Nero Sule) #1

Hi, I have an elasticsearch instance running on a shared environment, which has scripting disabled.

The data format is not set in stone, however for time being, I have documents such as this:

{
    "id" : "903c3bd0-369d-4349-a6ae-a6c100d7a0c2",
    "firstName" : "Test",
    "lastName" : "Carer",
    "radius" : 10.0000,
    "location" : {
	"lat" : 55.9748408074944,
	"lon" : -3.16677079753718
    }
}

The search query is about finding all documents by Geo distance, that are located no further than the radius specified in the document from the location specified in the document. I could do this using a script:

"filter": {
    "and": {
        "filters": [
	    {
		    "geo_distance": {
			    "location": [
				    55.9748408074944,
				    -3.16677079753718
			    ],
			    "distance": "3000mi"
			}
		},
		{
			"script": {
				"script": "doc['location'].arcDistanceInMiles(-3.16677079753718, 55.9748408074944) < doc['radius'].value"
			}
		}
	]
}

}

Now my question is... how can I achieve the same result WITHOUT using script?


(Christoph) #2

Hi,

one idea would be to change your document to index the location+radius together as a geo shape field. Then you could e.g. use a corresponding geo shape query to find all documents that intersect with a given point.

The slightly compromise in accuracy should not matter most of the time, and you can tune your configuration to give you the storage space / accuracy tradeoff that you need.


(Christoph) #3

I just wanted to try this out on a toy example myself, so for future reference:

PUT /index/
{
  "mappings": {
    "type": {
      "properties": {
        "location": {
          "type": "geo_shape",
          "tree": "quadtree",
          "precision": "1m"
        }
      }
    }
  }
}


PUT /index/type/1
{
  "foo" : "bar",
  "location" : {
        "type" : "circle",
        "coordinates" : [-3.16677079753718, 55.9748408074944],
        "radius" : "10km"
    }
}

GET /index/type/_search
{
    "query":{
        "bool": {
            "filter": {
                "geo_shape": {
                    "location": {
                        "shape": {
                            "type": "point",
                            "coordinates" : [-3.16677079753718, 55.8848408074944]
                        },
                        "relation": "intersects"
                    }
                }
            }
        }
    }
}

I didn't do any research and tuning on the geoshape mapping settings, 1m precision might be more than needed here and also the choice of quadtree is arbitrary. I played around with the reference point in the query and it seems to be doing what is expected. I cannot say much in terms of memory / storage / performance requirements compared to the script solution, but if that's no option then this is maybe a good starting point.


(system) #4

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