geo_distance doesn't return any hit Elasticsearch - elasticsearch

Have a problem with this query, when I use geo_distance filter, nothing returned from query. When I remove it I get proper results. Query is bellow:
GET _search
{
"query": {
"bool": {
"filter": {
"geo_distance": {
"distance": 20,
"distance_unit": "km",
"coordinates": [48.8488576, 2.3354223]
}
},
"must": {
"term": {
"_type": {
"value": "staff"
}
}
},
"must_not": [
{
"term": {
"cabinet.zipcode": {
"value": "75006"
}
}
},
{
"term": {
"next_availability_in_days": {
"value": "-1"
}
}
}
]
}
}
}
I would appreciate if someone gives me a hint.
UPDATE
When I run Elasticsearch Ruby DSL with same query logic, I get proper results:
<Elasticsearch::Model::Searching::SearchRequest:0x007ff335763560
#definition=
{:index=>["development_app_scoped_index_20170428134744",
"development_app_scoped_index_20170428134744"], :type=>["staff", "light_staff"],
:body=>
{:query=>
{:bool=>
{:must_not=>[
{:term=>{"cabinet.zipcode"=>75006}},
{:term=> {:next_availability_in_days=>-1}}
],
:must=>[
{:term=>{:_type=>"staff"}}
],
:filter=>{:geo_distance=>
{:coordinates=>
{:lat=>48.8488576, :lon=>2.3354223},
:distance=>"6km"
}
}}},
:sort=>[
{:type=>{:order=>"desc"}},
{"_geo_distance"=>{"coordinates"=>"48.8488576,2.3354223", "order"=>"asc",
"unit"=>"km"}},
{:next_availability_in_days=>{:order=>"asc"}},
{:priority=>{:order=>"asc"}}
]
}}
So this is really weird and I'm not sure what's going wrong in ES syntax, but it definitely should work as expected.
Thanks.

There is probably nothing in the range that you have entered.
Try to increase the "distance": 20 field to "distance": 500 and check the results then. For example the distance between these two geo points [0,0] and [0,1] is ~138.3414KM .
Another suggestion is to get rid of the "distance_unit" field and put the
and put the KM inside the "distance" field as following:
{
"query": {
"bool": {
"filter": {
"geo_distance": {
"distance": "20km",
"coordinates": [
48.8488576,
2.3354223
]
}
}
}
}
}

Related

In which order elasticsearch filters applied?

Currently I am using elasticsearch in my rails application. My concern is how filter works in query is there any priority or ranking that this filter will apply first and other one in last
OR it applied from top to bottom OR bottom to top :-
I have an example query with filter's below :-
{
"query": {
"constant_score": {
"filter": {
"bool": {
"must": [
{
"match_all": {
}
}
],
"filter": [
{
"term": {
"status": true
}
},
{
"geo_bounding_box": {
"location": {
"top_left": {
"lat": 40.8888,
"lon": -73.888888
},
"bottom_right": {
"lat": 41.8888,
"lon": -74.88888
}
}
}
},
{
"range": {
"get_booking_cut_off_time": {
"gte": 5.46
}
}
},
{
"terms": {
"show_to_list_val": [
"Both",
"Direct"
]
}
},
{
"range": {
"min_days": {
"lte": 1
}
}
},
{
"terms": {
"midoffice_master_id": [
10,
14
]
}
}
]
}
}
}
},
"_source": {
"includes": [
"name",
"code"
]
},
"size": 20,
"from": 0
}
So in above example I have term filter, geo_bounding_box filter and range filter. I want to know that which filter should be apply first or last when query hits the elasticsearch api ??
Any help would be appreciable... :)
Take a look at this very detailed blog post from Elastic about the inner workings of query- and filter-execution:
https://www.elastic.co/de/blog/elasticsearch-query-execution-order
In the Conclusion-section at the end they state (quote):
Q: Does the order in which I put my queries/filters in the query DSL matter?
A: No, because they will be automatically reordered anyway based on their respective costs and match costs.
Hope this helps!

ElasticSearch exclude result from being filtered where a condition is met

I want to exclude some results from being filtered by geo_distance where a condition is met.
For example, I filter my results on geo distance but I want to include all results where status is abnormal and meets the match_phrase query (even if it is outside the geo_distance)
GET /drive/_search
{
"query": {
"bool": {
"should": [
{
"match_phrase": {
"keywords": "wheels"
}
},
{
"match_phrase": {
"name": "car sale"
}
}
],
"filter": [
{
"term": {
"status": "normal"
}
},
{
"geo_distance": {
"distance": "0.09km",
"address.coordinate": {
"lat": -33.703082,
"lon": 18.981069
}
}
}
]
}
}
}
I've been reading the documentation and googling, but I think I might be going in the wrong direction.
If you can point me in the right direction, or explain to me what a better solution could be to do this Id be very grateful.
From the doc :
should
The clause (query) should appear in the matching document. If the bool
query is in a query context and has a must or filter clause then a
document will match the bool query even if none of the should queries
match. In this case these clauses are only used to influence the
score. If the bool query is in a filter context or has neither must or
filter then at least one of the should queries must match a document
for it to match the bool query. This behavior may be explicitly
controlled by setting the minimum_should_match parameter.
So in your case the geo condition is in "should" since it can be optional and the rest in "filter" which are mandatory : the status and match_phrase
Try this:
{
"query": {
"bool": {
"filter": [
{
"term": {
"status": "normal"
}
},
{
"match_phrase": {
"name": "car sale"
}
},
{
"match_phrase": {
"keywords": "wheels"
}
}
],
"should": [
{
"geo_distance": {
"distance": "0.09km",
"address.coordinate": {
"lat": -33.703082,
"lon": 18.981069
}
}
}
]
}
}
}

Elasticsearch geo distance query range

Hi for a project I am trying to return users from elastic search which are in a range of 2km to 4km away from the search user.
I use the below query
`
{
"size": 1000,
"from": 0,
"_source": "user_id",
"query":{
"bool":{
"must_not": {
"terms": {
"user_id": []
}
},
"filter":[
{
"geo_distance_range":{
"from":"2km",
"to": "4km",
"location":{
"lon":-122.4194,
"lat":37.7749
}
}
}
]
}
}
}`
This query is deleted in elastic search version 6.3 which is the version I am using.
Can anyone please help me solve this use case in elastic search 6.3? Aggregations only returns the number of users in the range but I want to return complete results of all users in the range.
I can't test this, but it seems reasonable that you should be able to combine must and must_not clauses with geo_distance:
"query": {
"bool": {
"must_not": {
"terms": {
"user_id": []
},
"geo_distance": {
"distance": "2km",
"location": [-122.4194, 37.7749]
}
},
"must": {
"geo_distance": {
"distance": "4km",
"location": [-122.4194, 37.7749]
}
}
}
}

Conditional filtering in Elasticsearch

I have an index with three fields type which is an integer, coordinates which is a geopoint and title which is a string. I want to query for matches on title. Then I want to filter my results conditionally. Records that are of type 2 should be included if they fall within a 15 km radius. Those that are not of type 2 should only be included if they fall within a 7.5 km radius. The query below does not achieve this; I rather included it to give some idea of the structure of my index. This query returns matching records that are of type 2 and fall within 15 km. I'd want this query to be expanded to also include matching records that aren't of type 2 (namely, 1), but only if they fall within 7.5 km. Is this achievable in a single ES query?
Pseudocode of my filtering conditions logic:
if type == 2
filter
distance: 15 km
else
filter
distance 7.5 km
Query:
{
"query": {
"filtered": {
"query": {
"match": {
"title": "my search terms"
}
},
"filter": {
"and": [
{
"geo_distance": {
"distance": "15km",
"coordinates": [
-79.3931,
43.6709
]
}
},
{
"term": {
"type": "2"
}
}
]
}
}
}
}
ES 2.3
You can achieve what you want like this:
{
"query": {
"bool": {
"must": {
"match": {
"title": "my search terms"
}
},
"should": [
{
"bool": {
"must": [
{
"geo_distance": {
"distance": "15km",
"coordinates": [
-79.3931,
43.6709
]
}
},
{
"term": {
"type": "2"
}
}
]
}
},
{
"bool": {
"must": [
{
"geo_distance": {
"distance": "7.5km",
"coordinates": [
-79.3931,
43.6709
]
}
}
],
"must_not": {
"term": {
"type": "2"
}
}
}
}
]
}
}
}

Elasticsearch filter on nested set

I'm having trouble figuring out how to filter on nested sets. I have this in my index:
PUT /testing
PUT /testing/_mapping/product
{
"product": {
"properties": {
"features": { "type": "nested" }
}
}
}
POST /testing/product
{
"productid": 123,
"features": [
{
"name": "Weight",
"nameslug": "weight",
"value": "10",
"valueslug": "10-kg"
},
{
"name": "Weight",
"nameslug": "weight",
"value": "12",
"valueslug": "12-kg"
}
]
}
I need to filter on value but I get the valueslug from the url. So far I have the following code:
POST _search
{
"query": {
"bool": {
"filter": [
{
"nested": {
"path": "features",
"query": {
"bool": {
"filter": [
{
"range": {
"features.value": { "gte": ??? }
}
}
]
}
}
}
}
]
}
}
}
The difficult part is resolving the valueslug to the actual value. I have looked into Script Query using doc_value, but the problem with that is that it is executed within the current nested document. It would be possible by execution two queries, but I am trying to avoid that (if possible).
I get the feeling that the solution lies in the way the documents should be structured, but I have no clue how I could structure this any different...
I hope anyone can point me in the right direction.
Thanks in advance!

Resources