Reputation: 2301
I have about 500 fixed polygons and I want to be able to check whether many points are in which of these polygons. maybe some points are within many of these polygons and some are not in any polygon at all. I know that elasticsearch geo_shape may help me but as I know I can only, query one point for knowing in which polygon it is.
so for example for 20 points I should connect to elasticsearch 20 times (consider rtt)
and if I load all polygons in my process and iterate over points and polygins there should be nested loop with count of 20 * 500 and in each cycle I should detect whether the point is in polygon or not so both speed of execution and also amount of memory this script need is not ok I think.
can any body help me with a better solution ?
Upvotes: 2
Views: 1283
Reputation: 217274
I think a better way would be to use the percolator
mapping type. First, create an index where you'll store your geo_shape
queries (in the queries
type). You also need to define the mapping of your points (in the points
type) so that ES knows what it is querying against:
PUT /my-index
{
"mappings": {
"points": {
"properties": {
"point": {
"type": "geo_shape"
}
}
},
"queries": {
"properties": {
"query": {
"type": "percolator"
}
}
}
}
}
Then, you can index one geo_shape
query for each of your already indexed polygon. Here we're defining a geo_shape
query for each polygon that you have already stored in polygon-index
:
PUT /my-index/queries/query-id-for-polygon-id
{
"query" : {
"geo_shape": {
"location": {
"indexed_shape": {
"index": "polygon-index",
"type": "polygon-type",
"id": "polygon-id",
"path": "polygon-field"
}
}
}
}
}
Finally, you can issue a single msearch
query containing one percolate
query for each of the points you want to check.
One percolate query for a single point would look like this. This query is basically saying: "find me all the polygon queries that contain the given point". As a result, you'll get a list of hits where each hit is a query and will contain the id of the polygon (query) that matches.
POST /my-index/_search
{
"query" : {
"percolate" : {
"field" : "query",
"document_type" : "points",
"document" : {
"point" : {
"type" : "point",
"coordinates" : [-77.03653, 38.897676]
}
}
}
}
}
So now you need to create one of those for each of the points you want to check in the following format:
POST /my-index/_search
{}
{"query": {"percolate": {"field": "query", "document_type" : "points", "document" : {"point" : {"type" : "point","coordinates" : [-77.03653, 38.897676]}}}}}
{}
{"query": {"percolate": {"field": "query", "document_type" : "points", "document" : {"point" : {"type" : "point","coordinates" : [-77.03653, 38.897676]}}}}}
{}
{"query": {"percolate": {"field": "query", "document_type" : "points", "document" : {"point" : {"type" : "point","coordinates" : [-77.03653, 38.897676]}}}}}
{}
{"query": {"percolate": {"field": "query", "document_type" : "points", "document" : {"point" : {"type" : "point","coordinates" : [-77.03653, 38.897676]}}}}}
...
You'll get back for each point, the polygons that contain it.
Upvotes: 1