Using geo_distance filter doesn't return any hits using ElasticSearch - 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"
}
}
}
}
}'

Related

Is it possible to use a more-like-this query on nested fields?

I have an "event" type based on a (nested) press article, including the title, and the text, which both have multifields.
I've tried :
{
"query":{
"nested":{
"path":"article",
"query":{
"mlt":{
"fields":["article.title.search","article.text.search"],
"max_query_terms": 20,
"min_term_freq": 1,
"include": "false",
"like":[{
"_index":"myindex",
"_type":"event",
"doc":{
"article":{
"title":"this is the title",
"text":"this is the body of the article"
}
}]
}
}
}
}
}
But it always returns 0 hits
{
"query": {
"nested":{
"path":"articles",
"query":{
"more_like_this" : {
"fields" : ["articles.brand", "articles.category", "articles.material"],
"like" : [
{
"_index" : "$index",
"_type" : "$type",
"_id" : "$id"
}
],
"min_term_freq" : 1,
"max_query_terms" : 20
}
}
}
}
This Works for me, Taking in consideration that the mapping of the nested fields you are using must be defined as term vectors.
"brand": {
"type": "string",
"index": "not_analyzed",
"term_vector": "yes"
}
Refer to: https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-mlt-query.html

Geo query using 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
}
}
}
}
}'

Filtering on Elasticsearch Optional Fields

I'm using Elasticsearch to query a document type, that has an optional location field. When searching, if that field does not exist, those results should be returned, as well as filtering on the results that do.
It seems like the OR filter in Elasticsearch does not short circuit, as this:
"query": {
"filtered": {
"query": {
"match_phrase_prefix": {
"display_name": "SearchQuery"
}
},
"filter": {
"or": [
{
"missing": {
"field": "location"
}
},
{
"geo_distance" : {
"distance" : "20mi",
"location" : {
"lat" : 33.47,
"lon" : -112.07
}
}
}
]
}
Fails with "failed to find geo_point field [location]".
Is there any way to perform this (or something along the same vein) in ES?
I don't know why yours isn't working but I've used the bool filter with great success in the past. The should option is essentially an or and makes sure at least one is true. Give it a try and comment on my answer if it still doesn't work. Also double check I copied your query terms properly :)
{
"filtered" : {
"query" : {
"match_phrase_prefix": {
"display_name": "SearchQuery"
}
},
"filter" : {
"bool" : {
"should" : [
{
"missing": { "field": "location" }
},
{
"geo_distance" : {
"distance" : "20mi",
"location" : {
"lat" : 33.47,
"lon" : -112.07
}
}
}
]
}
}
}
}
For anyone with the same issue, I kind of just hacked around it. For any documents that were missing a "location", I added one with a lat/lon of 0/0. Then I altered my query to be:
"filter": {
"or": [
{
"geo_distance": {
"distance": "0.1mi",
"location": {
"lat": 0,
"lon": 0
}
}
},
{
"geo_distance": {
"distance": "30mi",
"location": {
"lat": [lat variable],
"lon": [lon variable]
}
}
}
]
}

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 how to setup geo_point

I'm trying to setup a geo_point object on ES 1.0.0 and run a simple proof of concept query against it but the query is failing to return any hits. Here are my setup steps:
1) Create the mapping:
PUT jay/geotest/_mapping
{
"geotest" : {
"properties" : {
"name" : {
"type" : "string"
},
"pin" : {
"type": "geo_point"
}
}
}
}
2) verify the mapping:
GET jay/geotest/_mapping
3) Add a piece of data
put jay/geotest/1
{
"name": "test1",
"pin": {
"lat": 0,
"lon": 0
}
}
4) query for that data:
GET jay/geotest/_search?search_type=count
{
"filtered" : {
"filter" : {
"geo_distance" : {
"distance" : "100km",
"pin" : {
"lat" : 0,
"lon" : 0
}
}
}
}
}
My expected result is that I will get one hit returned but instead nothing is returned by the query.
Thanks in advance!
I think you're missing the "query" part of the request.
POST jay/geotest/_search
{
"query": {
"filtered": {
"filter": {
"geo_distance": {
"distance": "100km",
"pin": {
"lat": 0,
"lon": 0
}
}
}
}
}
}
I've just tested your steps, and making that change returns the document.

Resources