Geo query using elasticsearch - elasticsearch

I have created and index the same as the example tutorials, in here...
https://www.elastic.co/guide/en/elasticsearch/reference/2.0/geo-point.html
in specific writing the following:
curl -PUT 'localhost:9200/my_index?pretty' -d '
{
"mappings": {
"my_type": {
"properties": {
"location": {
"type": "geo_point"
}
}
}
}
}'
I have also added two points as data
curl -PUT 'localhost:9200/my_index/my_type/1?pretty' -d'
{
"text": "first geo-point",
"location": {
"lat": 41.12,
"lon": -71.34
}
}'
curl -PUT 'localhost:9200/my_index/my_type/1?pretty' -d'
{
"text": "second geo-point",
"location": {
"lat": 41.13,
"lon": -71.35
}
}'
The example geo bounding box query on the page works (i.e):
curl -XGET 'localhost:9200/my_index/_search?pretty' -d'
{
"query": {
"geo_bounding_box": {
"location": {
"top_left": {
"lat": 42,
"lon": -72
},
"bottom_right": {
"lat": 40,
"lon": -74
}
}
}
}
}'
But the example from this page (https://www.elastic.co/guide/en/elasticsearch/reference/2.0/query-dsl-geo-bounding-box-query.html) doesn't work:
What I have tried looks like the following:
curl -XGET 'localhost:9200/my_index/_search?pretty' -d'
{
"bool" : {
"must" : {
"match_all" : {}
},
"filter" : {
"geo_bounding_box" : {
"my_type.location" : {
"top_left" : {
"lat" : 42,
"lon" : -72
},
"bottom_right" : {
"lat" : 40,
"lon" : -74
}
}
}
}
}
}'
The error I get is as follows:
"error" : {
"root_cause" : [ {
"type" : "search_parse_exception",
"reason" : "failed to parse search source. unknown search element [bool]",
"line" : 3,
"col" : 5
} ],
"type" : "search_phase_execution_exception",
"reason" : "all shards failed",
"phase" : "query",
"grouped" : true,
"failed_shards" : [ {
"shard" : 0,
"index" : "my_index",
"node" : "0qfvkynhTRyjHFRurBLJeQ",
"reason" : {
"type" : "search_parse_exception",
"reason" : "failed to parse search source. unknown search element [bool]",
"line" : 3,
"col" : 5
}
} ]
},
"status" : 400
}
I hope its just a simple error, so would like to know what am i doing wrong?

You need to specify that the whole thing is a query:
curl -XGET 'localhost:9200/my_index/_search?pretty' -d'
{
"query": {
"bool" : {
"must" : {
"match_all" : {}
},
"filter" : {
"geo_bounding_box" : {
"my_type.location" : {
"top_left" : {
"lat" : 42,
"lon" : -72
},
"bottom_right" : {
"lat" : 40,
"lon" : -74
}
}
}
}
}
}
}'
However as far as I understand using bool with must and filter is the old way of doing things. In previous versions, geo queries were thought of as "filters", so you had to first run a match_all query to return all the results, and then filter using the geo bounding box. In Elasticssearch 2.0+, there is no separation between filters and queries - everything is a query. So you can run the geo query directly:
curl -XGET 'localhost:9200/my_index/_search?pretty' -d'
{
"query": {
"geo_bounding_box": {
"location": {
"top_left": {
"lat": 42,
"lon": -72
},
"bottom_right": {
"lat": 40,
"lon": -74
}
}
}
}
}'

Related

How to find out what is my index sorted by in elasticsearch?

I created new index in elasticsearch (v6) using command:
curl -XPUT -H 'Content-Type: application/json' http://localhost:9200/sorttest -d '
{
"settings" : {
"index" : {
"sort.field" : ["username", "date"],
"sort.order" : ["asc", "desc"]
}
},
"mappings": {
"_doc": {
"properties": {
"username": {
"type": "keyword",
"doc_values": true
},
"date": {
"type": "date"
}
}
}
}
}
'
The response was
{"acknowledged":true,"shards_acknowledged":true,"index":"sorttest"}
Next I checked out generated mapping
curl -XGET localhost:9200/sorttest/_mapping?pretty
And the result was
{
"sorttest" : {
"mappings" : {
"_doc" : {
"properties" : {
"date" : {
"type" : "date"
},
"username" : {
"type" : "keyword"
}
}
}
}
}
}
The question is: how can I find out what kind of sorting is set for my index?
Just
curl -XGET localhost:9200/sorttest?pretty
and you will see:
"settings" : {
"index" : {
...
"sort" : {
"field" : [
"username",
"date"
],
"order" : [
"asc",
"desc"
]
},
...
}
}

Using geo_distance filter doesn't return any hits using ElasticSearch

I can't get my filter query to work correctly with geo_distance. It seems to return 0 hits. But all of my other queries work if I'm not trying to find a geo position.
I'm using version 2.3.1 of ElasticSearch
{
"name" : "Mar-Vell",
"cluster_name" : "elastic-logs",
"version" : {
"number" : "2.3.1",
"build_hash" : "bd980929010aef404e7cb0843e61d0665269fc39",
"build_timestamp" : "2016-04-04T12:25:05Z",
"build_snapshot" : false,
"lucene_version" : "5.5.0"
},
"tagline" : "You Know, for Search"
}
I've mapped my location key with a type of "geo_point" by making a request with json like so:
curl -XPUT 'http://10.0.7.181:9200/connections/profile/_mapping' -d '
{
"profile" : {
"properties" : {
"location" : {
"type" : "geo_point"
}
}
}
}
And it returns this. I'm assuming my changes are in affect.
{"acknowledged":true}
Here's an example of my data
{
"_index": "connections",
"_type": "profile",
"_id": "92",
"_score": 1,
"_source": {
"profile": {
"location": {
"lon": -111.8909815,
"lat": 40.7607818
},
"age": 44,
"school": {
"undergraduate": {
"universityId": 1814,
"active": true,
"programId": 9
},
"graduate": {
"universityId": 1814,
"active": true,
"programId": 7
}
},
"bio": "Everything is awesome! 👽"
},
"id": 0,
"active": false,
"optIn": true
}
}
My query that I'm sending over to our ElasticSearch. Nothing crazy.
{
"filter" : {
"geo_distance" : {
"distance" : "1000mi",
"distance_type": "plane",
"location" : {
"lon": -111.8391029,
"lat": 40.7607818
}
}
},
"query" : {
"match_all" : {}
}
}
I've tried changing the distance to 1 mile, 100 miles and 1000 miles. It should return something with 100 miles but no show. I've also tried using different unit measurements just to see if it would do anything. The same deal.
The coordinates are in Salt Lake City. And the order of longitude and latitude should be right. I'm not sure what else I should try.
The name of your location field is location, but in your query you are using geoPoint as the field name. Try this:
{
"filter" : {
"geo_distance" : {
"distance" : "1000mi",
"distance_type": "plane",
"location" : {
"lon": -111.8391029,
"lat": 40.7607818
}
}
},
"query" : {
"match_all" : {}
}
}
Update: Ok, that was the obvious mistake i saw so I didn't look any further. Here is a working query(with your values) from one of my projects:
{
"query": {
"bool": {
"must": {
"match_all": []
},
"filter": {
"geo_distance": {
"distance": "1000mi",
"distance_type": "plane",
"location": {
"lat": "-111.8391029",
"lon": "40.7607818"
}
}
}
}
}
}
That should work.
#Pelmered thanks for helping me with the filter query. I found out that my mapping was done incorrectly. Now everything works as expected. So make sure you are mapping it correctly.
curl -XPUT 'http://10.0.7.181:9200/connections' -d '
{
"mappings":{
"profile":{
"properties":{
"location":{
"type":"geo_point"
}
}
}
}
}'

Elasticsearch Geospatial giving me exaggerated distance measurements

Problem:
I am using Elasticsearch to index some listings on my site and I keep getting ridiculously exaggerated distances. Even when I search using the same coordinates my document has I still get distances upward of 3000km.
Post:
[{
"expiryDate": "2014-04-11 02:32:16",
"geo": {
"lon": 45.297,
"lat": 75.0755
},
"id": "5571afb7ae2c287f4d54b713",
"images": [],
"imagesLinks": [],
}]
Mapping:
{
"listingsell" : {
"properties" : {
"geo" : {
"type" : "geo_point",
"fielddata" : {
"format" : "compressed",
"precision" : "1m"
}
}
}
}
}
Query:
{
"query": {
"filtered" : {
"query" : {
"match_all" : {}
},
"filter" : {
"geo_distance" : {
"distance" : "90000mi",
"geo" : {
"lat" : 45.1339,
"lon" : 75.019
}
}
}
}
},
"sort" : [
{
"_geo_distance" : {
"geo" : {
"lat" : 45.1339,
"lon" : 75.019
},
"order" : "asc",
"unit" : "mi"
}
}
],
}
Result :
{
"sort":[2247.4929]
}
You have the geo_point indexed in a wrong way:
"geo": {
"lon": 45.297,
"lat": 75.0755
}
or the sorting is done in a wrong way:
"geo" : {
"lat" : 45.1339,
"lon" : 75.019
}
Meaning you mixed up lat with lon.

Is it possible to have more than one geo_point index in a ElasticSearch document?

I have the following mapping for a type:
{
"myType":
"properties": {
"departure": {"type": "geo_point" },
"destination": {"type": "geo_point" }
}
}
I can insert documents without any trouble. But when I try to filter them by departure I get no results and when I try by destination it works just fine.
So the question is: Is it possible to have more than one geo_point in the same document?
EDIT:
Sample document:
{
"departure": {
"lat": -23.682,
"lon": -46.595
},
"destination": {
"lat": -22.895,
"lon": -47.030
}
}
Sample query:
curl -XGET 'http://localhost:9200/tripda/trip/_search?pretty=true' -d '
{
"query": {
"filtered" : {
"query" : {
"match_all" : {}
},
"filter" : {
"geo_distance" : {
"distance" : "15km",
"departure" : {
"lat" : -23.682,
"lon" : -46.595
}
}
}
}
}
}'
Thanks!

elasticsearch geo_point don't work properly

I want to make geo_point queries on elasticsearch but it doesn't work properly for me. I always get empty result for geo_polygon queries. maybe my mapping is wrong or the way i get the data.
mapping :
curl -XPUT 'localhost:9200/botanique_localisation/' -d '{
"mappings":{
"botanique_localisation" : {
"_all" : {"enabled" : true},
"_index" : {"enabled" : true},
"_id" : {"index": "not_analyzed", "store" : false},
"properties" : {
"_id" : {"type" : "string", "store" : "no","index": "not_analyzed" } ,
"LOCATION" : { "type" : "geo_point","lat_lon" :true ,"validate":true , "store":"yes" }
}
}
}
}'
creating the view in oracle
create view all_specimens_localisation as select RAWTOHEX( SPECIMENS.occurrenceid ) as "_id" ,
decode(LOCALISATIONS.decimalLatitude ||',' || LOCALISATIONS.decimalLongitude, ',', null ,
'{"lat":' || replace(LOCALISATIONS.decimalLatitude,',' ,'.' ) ||',"lon":' || replace(LOCALISATIONS.decimalLongitude , ',' ,'.' ) || '}'
) as location
from SPECIMENS left outer join ... where rownum < 1000 ;
i create a json object in the sql because sending lat_lon as a string didn't work for me ( elastic don't split the string as write her http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/mapping-geo-point-type.html#_lat_lon_as_string_6 )
creating the river from oracle to elasticsearch
curl -XPUT 'localhost:9200/_river/localisation_river/_meta' -d '{
"type" : "jdbc",
"jdbc" : {
"index" : "botanique_localisation",
"bulk_size" : 2000,
"max_bulk_requests" : 10,
"bulk_flush_interval" : "1s",
"type" : "specimens",
"url" : "********",
"user" : "********",
"password" : "********",
"sql" : "select * from all_specimens_localisation"
}
}'
exemple of indexed data in elastichsearch
{
_index: botanique_localisation
_type: specimens
_id: 38C8F872A449491C881791DE8B501B17
_score: 1.4142135
_source: {
LOCATION: {
lon: 47.05
lat: -19.95
}
}
}
working range query
curl -XGET 'localhost:9200/botanique_localisation/specimens/_search?size=10&pretty' -d '
{ "query": { "bool": { "must": [
{ "range": {
"LOCATION.lon": {
"from": 47.04,
"to": 47.08
}
}
},{ "range": {
"LOCATION.lat": {
"from": -20,
"to": -19.90
}
}
}
]}}}'
and the result :
hits:{[
{ "_index": botanique_localisation,
"_type": specimens,
"_id": 38C8F872A449491C881791DE8B501B17,
"_score": 1.4142135,
"_source": {
"LOCATION": { "lon": 47.05, "lat": -19.95 }
}
},...
now the fun not working part ! with the geo_polygon query :
curl -XGET 'localhost:9200/botanique_localisation/_search?size=10&pretty' -d '{
"query":{
"filtered" : {
"query" : { "match_all" : {}},
"filter" : {
"geo_polygon" : {
"LOCATION" : {
"points" : [
{ "lat": 100, "lon": -100},
{ "lat": 100, "lon": 100},
{ "lat": -100, "lon": 100 },
{ "lat": -100 , "lon": -100 }
]
}
}
}
}
}
}'
this return no hits !
what i'm missing ?
thank you
this query work :
curl -XGET 'localhost:9200/botanique_localisation/_search?pretty' -d '{
"query" : {
"filtered" : {
"filter" : {
"geo_bounding_box" : {
"type" : "indexed",
"LOCATION" : {
"top_left" : {
"lat" : 50,
"lon" : -50
},
"bottom_right" : {
"lat" :-50,
"lon" : 50
}
}
}
}
}
}
}'

Resources