I am facing am issue, I know how to find all geo_points in a particular radius but I need to find how many regions or geo_shape a particular point lies in. To solve this issue, I have made following index:
PUT /users
And this mapping:
PUT /users/_mapping/_doc
{
"properties": {
"radius": {
"type": "geo_shape",
"tree": "quadtree",
"precision": "100m"
},
"point":{
"type":"geo_point"
}
}
}
Also following is the sample document:
POST /users/_doc
{
"radius":{
"type" : "circle",
"coordinates" : [28.363157, 77.287550],
"radius" : "100km"
},
"point":{
"lat" : 28.363157,
"lon": 77.287550
}
}
The query I am making is:
POST /users/_search
{
"query":{
"bool": {
"must": {
"match_all": {}
},
"filter": {
"geo_shape": {
"radius": {
"shape": {
"type": "point",
"coordinates" : [29.363157, 77.28755]
},
"relation": "contains"
}
}
}
}
}
}
Now, the distance between the latlongs in query and doc is almost 110-112kms, hence above query returns exact result, but when I query [30.363157, 77.28755], it still returns the document even when the distance is over 220kms.
What am I doing wrong?
Related
How can I find polygons that stored in elastic index.
Simple mapping:
PUT /regions
{
"mappings": {
"properties": {
"location": {
"type": "geo_shape"
}
}
}
}
And simple polygon:
/regions/_doc/1
{
"location" : {
"type" : "polygon",
"coordinates" : [
[
[53.847332102970626,27.485155519098047],
[53.84626875748117,27.487134989351038],
[53.8449047241684,27.48501067981124],
[53.84612634308789,27.482945378869765],
[53.847411219859,27.48502677306532],
[53.847332102970626,27.485155519098047]
]
]
}
}
According to documentation I can only search coordinates within polygon only if the polygon is contained in the request Geo-polygon query, but I need to find polygons by coordinates in query. Elasticsearch 7.6 version.
Query:
{
"query": {
"match_all": {}
},
"filter": {
"geo_shape": {
"geometry": {
"shape": {
"coordinates": [
53.846415,
27.485756
],
"type": "point"
},
"relation": "whithin"
}
}
}
}
You were on the right path but your query was heavily malformed. Here's the fix:
{
"query": {
"bool": {
"filter": {
"geo_shape": {
"location": {
"shape": {
"coordinates": [
53.846415,
27.485756
],
"type": "point"
},
"relation": "intersects"
}
}
}
}
}
}
Notice how I used intersects instead of within. The reason is explained in this GIS StackExchange answer.
I am trying to understand how elastic search supports Geo Spatial search internally.
For the basic search, it uses the inverted index; but how does it combine with the additional search criteria like searching for a particular text within a certain radius.
I would like to understand the internals of how the index would be stored and queried to support these queries
Text & geo queries are executed separately of one another. Let's take a concrete example:
PUT restaurants
{
"mappings": {
"properties": {
"location": {
"type": "geo_point"
},
"menu": {
"type": "text",
"fields": {
"keyword": {
"type": "keyword"
}
}
}
}
}
}
POST restaurants/_doc
{
"name": "rest1",
"location": {
"lat": 40.739812,
"lon": -74.006201
},
"menu": [
"european",
"french",
"pizza"
]
}
POST restaurants/_doc
{
"name": "rest2",
"location": {
"lat": 40.7403963,
"lon": -73.9950026
},
"menu": [
"pizza",
"kebab"
]
}
You'd then match a text field and apply a geo_distance filter:
GET restaurants/_search
{
"query": {
"bool": {
"must": [
{
"match": {
"menu": "pizza"
}
},
{
"geo_distance": {
"distance": "0.5mi",
"location": {
"lat": 40.7388,
"lon": -73.9982
}
}
},
{
"function_score": {
"query": {
"match_all": {}
},
"boost_mode": "avg",
"functions": [
{
"gauss": {
"location": {
"origin": {
"lat": 40.7388,
"lon": -73.9982
},
"scale": "0.5mi"
}
}
}
]
}
}
]
}
}
}
Since the geo_distance query only assigns a boolean value (--> score=1; only checking if the location is within a given radius), you may want to apply a gaussian function_score to boost the locations that are closer to a given origin.
Finally, these scores are overridable by using a _geo_distance sort where you'd order by the proximity (while of course keeping the match query intact):
...
"query: {...},
"sort": [
{
"_geo_distance": {
"location": {
"lat": 40.7388,
"lon": -73.9982
},
"order": "asc"
}
}
]
}
Suppose I have the following mapping:
"mappings": {
"doc": {
"properties": {
"name": {
"type": "text"
},
"location": {
"type": "nested",
"properties": {
"point": {
"type": "geo_shape"
}
}
}
}
}
}
}
There is one document in the index:
POST /example/doc?refresh
{
"name": "Wind & Wetter, Berlin, Germany",
"location": {
"type": "point",
"coordinates": [13.400544, 52.530286]
}
}
How can I make a nested geo-shape query?
Example of usual geo-shape query from the documentation (the "bool" block can be skipped):
{
"query":{
"bool": {
"must": {
"match_all": {}
},
"filter": {
"geo_shape": {
"location": {
"shape": {
"type": "envelope",
"coordinates" : [[13.0, 53.0], [14.0, 52.0]]
},
"relation": "within"
}
}
}
}
}
}
Example of a nested query is:
{
"query": {
"nested" : {
"path" : "obj1",
"score_mode" : "avg",
"query" : {
"bool" : {
"must" : [
{ "match" : {"obj1.name" : "blue"} },
{ "range" : {"obj1.count" : {"gt" : 5}} }
]
}
}
}
}
}
Now how to combine them? In the documentation it is mentioned that nested filter has been replaced by nested query. And that it behaves as a query in “query context” and as a filter in “filter context”.
If I try query for intersect with the point:
{
"query": {
"nested": {
"path": "location",
"query": {
"geo_shape": {
"location.point": {
"shape": {
"type": "point",
"coordinates": [
13.400544,
52.530286
]
},
"relation": "disjoint"
}
}
}
}
}
}
I still get back the document even if relation is "disjoint", so it's not correct. I tried different combinations, with "bool" and "filter", etc. but query is ignored, returning the whole index. Maybe it's impossible with this type of mapping?
Clearly I am missing something here. Can somebody help me out with that, please? Any help is greatly appreciated.
Sorry for the noob question... I have Restaurant objects in Elasticsearch 2.3, each has a GeoPoint and a home delivery distance preference. In pseudocode
restaurant: {
location: (x, y)
deliveryPreference: 10km
}
and a user:
user {
location: (a,b)
}
How would I issue a search for a user looking for all restaurants that can deliver in his area?
The solution involves using geo_shapes. You need to model the restaurant documents as follows:
PUT restaurants
{
"mappings": {
"restaurant": {
"properties": {
"name": {
"type": "text"
},
"location": {
"type": "geo_point"
},
"delivery_area": {
"type": "geo_shape",
"tree": "quadtree",
"precision": "1m"
}
}
}
}
}
You can then index your restaurants as follows:
POST /restaurants/restaurant/1
{
"name": "My Food place",
"location": [-45.0, 45.0], <-- lon, lat !!!
"delivery_area": {
"type": "circle",
"coordinates" : [-45.0, 45.0], <-- lon, lat !!!
"radius" : "10km"
}
}
Each restaurant will thus be associated with a circle shape centered on its location and with a proper radius.
Finally, when a user wants to know which restaurant can deliver at the location she is currently at, you can issue the following geo_shape query:
POST /restaurants/_search
{
"query":{
"bool": {
"filter": {
"geo_shape": {
"delivery_area": {
"shape": {
"type": "point",
"coordinates" : [<user_lon>, <user_lat>]
},
"relation": "contains"
}
}
}
}
}
}
In this query, we are retrieving restaurants whose delivery_area shape contains the point the user is currently located at.
Index the restraunts documents with following mappings
{
"mappings": {
"type_name": {
"properties": {
"name": {
"type": "text"
},
"location": {
"type": "text"
},
"location_geo": {
"type": "geo_point"
}
}
}
}
}
Use geo_filter query
{
"query": {
"bool": {
"filter": {
"geo_distance": {
"distance": "10km",
"location_geo": {
"lat": 40,
"lon": -70
}
}
}
}
}
}
I have 'shapes' index that stores a lot of huge geoshapes (original shapefile for one geoshape was 6MB in size).
I'm using this mapping:
"shape": {
"type": "geo_shape",
"tree": "quadtree",
"tree_levels": "20"
},
"_all": {
"enabled": false
},
"dynamic": "true"
I also have 'photos' index. Each photo have latitude and longitude presented as geoshape with type Point.
e.g.
"location": {
"type": "Point",
"coordinates": [
-103.262600,
43.685315
]
}
Mapping for it:
"location": {
"type": "geo_shape",
"tree": "quadtree",
"tree_levels": 20
}
I'm trying to find all photos that located inside selected shape by using following query:
GET photos/_search
{
"query": {
"filtered": {
"filter": {
"geo_shape": {
"location": {
"relation": "intersects",
"indexed_shape": {
"id": "huge_region_shape_id",
"type": "country",
"index": "shapes",
"path": "shape"
}
}
}
},
"query": {
"match_all": {}
}
}
}
}
Issues:
1) On a huge shapes this query executes several minutes or forever.
2) Just searching shapes by some parameters takes a lot of time if "shape" included into source, but if I exclude it - geo_shape filter will throw an exception - "Shape found but missing field"
In mapping:
_source: {
excludes : ['shape']
}
Is there some way to solve this issues?