Elasticsearch is a powerful search engine that supports geographic queries, but not everyone is used to working with spatial data. If you don’t know much about geohandling, or want to learn about geohandling through Elasticsearch, this article is for you. In our real life, we often use Didi Dache, Meituan Food Delivery, Uber, Lyft, and some dating apps, all of which are examples of Elasticsearch for location search.
Geo distance query
The geographic distance query returns all documents with the maximum distance from a point, for example: Dolores wants to know everyone who is about 300 meters away from her:
The red circle has a radius of 300 meters, and we can see that only William is inside the circle.
Let’s do the implementation of Elasticsearch. First, create a user_Location index using the attributes Name and location.
PUT user_location
{
"mappings": {
"properties": {
"name": {
"type": "text"
},
"location": {
"type": "geo_point"
}
}
}
}
Copy the code
The data type of location is geo_point, which represents a location on the earth. A point has longitude and latitude (coordinates). You can check all acceptable GEO_point formats in the official documentation.
Now, let’s document the locations of William, Robert, and Bernard. We use the _bulk API to import data:
POST user_location/_bulk { "index" : { "_id" : "1" } } { "name" : "William", "location": "25.443053, 49.238396} {" index" : {" _id ":" 2 "}} {" name ":" Robert ", "location" : "25.440173, 49.243169} {" index" : {" _id ":" 3 "}} {" name ":" Bernard ", "location" : "25.440262, 49.247720}"Copy the code
To illustrate, I created a new index called Locations that contains Dolores location information:
PUT locations
{
"mappings": {
"properties": {
"name": {
"type": "text"
},
"location": {
"type": "geo_point"
}
}
}
}
Copy the code
POST locations/_bulk { "index" : { "_id" : "1" } } { "name" : "William", "location": "25.443053, 49.238396} {" index" : {" _id ":" 2 "}} {" name ":" Robert ", "location" : "25.440173, 49.243169} {" index" : {" _id ":" 3 "}} {" name ":" Bernard ", "location" : "25.440262, 49.247720} {" index" : {" _id ":" 4 "}} {" name ":" green ", "location" : "25.442987, 49.239504}"Copy the code
The file with id 4 above is Doloes’ location. Let’s create an index pattern called Locations:
Let’s open the Maps app:
We found that these four locations were located somewhere in South America. We edit the location layer Settings to display the name and ID when we click on the location. Let’s adjust the appropriate zoom size:
From the picture above, we can see clearly where everyone is relative to each other. The closest person to Dolores is Willam, the covered one, and then Robert. The farthest is Bernard. Notice that all of our presentations above are based on locations index. It has Dolores in it. We now use the user_Location index to search:
GET user_location/_search { "query": { "bool": { "filter": { "geo_distance": { "distance": "300m", "location": "-25.442987, -49.239504"}}}}}Copy the code
Above, we search for Dolores. The results are as follows:
{ "took" : 55, "timed_out" : false, "_shards" : { "total" : 1, "successful" : 1, "skipped" : 0, "failed" : , "hits" : {0} "total" : {" value ": 1, the" base ":" eq "}, "max_score" : 0.0, "hits" : [{" _index ": "User_location _type", "" :" _doc ", "_id" : "1", "_score" : 0.0, "_source" : {" name ":" William ", "location" : "-25.443053, -49.238396"}}]}Copy the code
So within 300 meters of Dolores, there was only William. If we increase the radius to 600 m, then I can see Robert:
GET user_location/_search { "query": { "bool": { "filter": { "geo_distance": { "distance": "600m", "location": "-25.442987, -49.239504"}}}}}Copy the code
{ "took" : 2, "timed_out" : false, "_shards" : { "total" : 1, "successful" : 1, "skipped" : 0, "failed" : 0 }, "hits" : {" total ": {" value" : 2, the "base" : "eq"}, "max_score" : 0.0, "hits" : [{" _index ":" user_location ", "_type" : "_doc", "_id" : "1", "_score" : 0.0, "_source" : {" name ":" William ", "location" : "25.443053, 49.238396}}, {" _index" : "user_location", "_type" : "_doc", "_id" : "2", "_score" : 0.0, "_source" : {" name ":" Robert ", "location" : "25.440173, 49.243169}}}}]Copy the code
Geo polygon query
A geographic polygon query retrieves documents within a polygon.
“Polygons are closed shapes with straight sides. Rectangles, triangles, hexagons, and octagons are examples of polygons.”
It’s represented by a list of points. The closest path between two points is a straight line. Polygons start and end at the same point. Check out the botanical Garden polygon below on the figure below.
Note that the geography query on Elasticsearch checks if the document’s geo_point attribute is in a polygon. Example: Dolores wants to know everyone in the botanical garden.
GET user_location/_search { "query": { "bool": { "filter": { "geo_polygon": { "location": { "points": [25.44373, 49.24248, 25.44297, 49.24230, 25.44177, 49.23642, 25.43961, 49.23822, 25.43991, 49.23781, "25.44170, 49.23647, 25.44210, 49.23586", 25.44218, 49.23506, 25.44358, 49.23491, 25.44406, 49.24139, "-25.44373,-49.24248"]}}}}}}Copy the code
The search above returns:
{ "took" : 15, "timed_out" : false, "_shards" : { "total" : 1, "successful" : 1, "skipped" : 0, "failed" : , "hits" : {0} "total" : {" value ": 1, the" base ":" eq "}, "max_score" : 0.0, "hits" : [{" _index ": "User_location _type", "" :" _doc ", "_id" : "1", "_score" : 0.0, "_source" : {" name ":" William ", "location" : "-25.443053, -49.238396"}}]}Copy the code
In this article, you learned what geopoints and geopolygons are, and how to implement geo_distance and geo_polygon queries through Elasticsearch. I hope this article has helped you in your intellectual journey.