Performance difference between nested bool queries and non nested bool queries in Elastic search - elasticsearch

Was wondering if there's a big difference in performance between these two queries which get the same results
{
"query": {
"bool": {
"must": [
"bool": {
"must": [
{
"term": {
"color": "red"
}
},
{
"term": {
"fruit": "strawberry"
}
}
]
}
}
}
}
}
and
{
"query": {
"bool": {
"must": [
{
"term": {
"color": "red"
}
},
{
"term": {
"fruit": "strawberry"
}
}
]
}
}
}

The execution plan of both queries is exactly the same. Add ?explain=true to your URL so you can see how both queries are "explained".
The performance improvement would come from using filter instead of must provided you don't need scoring but only yes/no filtering, i.e.:
{
"query": {
"bool": {
"filter": [ <-- change this
{
"term": {
"color": "red"
}
},
{
"term": {
"fruit": "strawberry"
}
}
]
}
}
}

Related

Elasticsearch constant_score wrapped inside must does not return expected result

I have the following ES query :
{
"query": {
"bool": {
"should": [
{
"constant_score": {
"boost": 5,
"filter": {
"bool": {
"must": [
{
"ids": {
"values": [
"winnerAthlete-A"
]
}
},
{
"dis_max": {
"queries": [
{
"bool": {
"filter": {
"term": {
"isAthlete": true
}
}
}
},
{
"bool": {
"filter": {
"term": {
"isWinner": true
}
}
}
}
]
}
}
]
}
}
}
},
{
"constant_score": {
"boost": 4,
"filter": {
"bool": {
"must": [
{
"ids": {
"values": [
"winnerAthlete-B"
]
}
},
{
"dis_max": {
"queries": [
{
"bool": {
"filter": {
"term": {
"isAthlete": true
}
}
}
},
{
"bool": {
"filter": {
"term": {
"isWinner": true
}
}
}
}
]
}
}
]
}
}
}
}
]
}
}
}
It does return the result I expect : the 2 documents winnerAthlete-A and winnerAthlete-B, assigning a score of 5.0 to winnerAthlete-A and a score of 4.0 to winnerAthlete-B.
Now, when I turn the should on the third line of the query into a must, the query does not match any document whereas I would expect the exact same result. I can't wrap my head around why. I have tried using the ES _explain keyword to understand why this query doesn't match when using must but it didn't help me.
Any idea why this query rewritten with a must does not return anything whereas the should version does return the expected result ?
Should works like "OR" . It will return a document which matches any of clauses.
Must works like "AND" . Document must satisfy both clauses.
Your query is not returning any result because there is no single document which has ids as winnerAthlete-A as well as winnerAthlete-B

How do i combine different search parameters in an elasticscearch dsl query?

Good day together,
I have a little problem in Elastic/Kibana. In the Kibana Query Language "KQL" it is possible for me to execute a certain query:
car:* AND coun: * AND doc: (bes* OR *rvr*) AND NOT coun: (SIP OR LUK)
I would like to use this as a filter query using Elasticscearch query DSL. Only I don't get the same result. For this I use the boolean operator. My query looks like this:
{
"query": {
"bool": {
"must": [
{
"exists": {
"field": "car"
}
},
{
"exists": {
"field": "coun"
}
}
],
"should": [
{
"wildcard": {
"doc.keyword": {
"value": "bes*"
}
}
},
{
"wildcard": {
"doc.keyword": {
"value": "*rvr*"
}
}
}
],
"must_not": [
{
"term": {
"coun.keyword": "SIP"
}
},
{
"term": {
"coun.keyword": "LUK"
}
}
],
"minimum_should_match": 1
}
}
}
Unfortunately, I do not get the same result. My guess is the "should" operator. But I don't know exactly how to adjust the code.
I would be very grateful for any answer! Thanks a lot!
Problem here, that you putting OR outside AND. Just move should clause inside must. Like this
GET _search
{
"query": {
"bool": {
"must": [
{
"exists": {
"field": "car"
}
},
{
"exists": {
"field": "con"
}
},
{
"bool": {
"should": [
{
"wildcard": {
"doc.keyword": {
"value": "bes*"
}
}
},
{
"wildcard": {
"doc.keyword": {
"value": "*rvr*"
}
}
}
]
}
}
],
"must_not": [
{
"term": {
"coun.keyword": "SIP"
}
},
{
"term": {
"coun.keyword": "LUK"
}
}
],
"minimum_should_match": 1
}
}
}

Simplest way to query a elasticsearch index with chained conditions

I have an index of products on which I want to find all the products who fulfill conditions , such as :
((type = "orange" and price > 10) or (type = "apple" and price > 8)) and on_sale=True.
What about
(type = "orange" or type = "apple") and (price <= 25 or on_sale=True) .
You need to combine bool clauss, with "must" and "should".
Find below the required query for the first statement
GET _search
{
"query": {
"bool": {
"must": [
{
"term": {
"on_sale": {
"value": "True"
}
}
},
{
"bool": {
"should": [
{
"bool": {
"must": [
{
"term": {
"type": {
"value": "orange"
}
}
},
{
"range": {
"price": {
"gte": 10
}
}
}
]
}
},
{
"bool": {
"must": [
{
"term": {
"type": {
"value": "apple"
}
}
},
{
"range": {
"price": {
"gte": 8
}
}
}
]
}
}
]
}
}
]
}
}
}
It is just about wrapping "must" or "Should" clauses into one another as required. You need a little bit of practise to figure out how to chain them. But literally any combination can be queried using this kind of syntax.
For the second query:
{
"query": {
"bool": {
"must": [
{
"terms": {
"type": [
"ornage",
"apple"
]
}
},
{
"bool": {
"should": [
{
"term": {
"on_sale": {
"value": "True"
}
}
},
{
"range": {
"price": {
"gte": 10
}
}
}
]
}
}
]
}
}
}
When you need "and" use "MUST", when you need "or" use "SHOULD".
HTH.

Should as filter context (OR without scoring in Elasticsarch possible?)

I am trying to setup most efficient way to build an OR without having a scoring, since I want to order my results by business values afterwards.
Unfortunately i don't get it done. :(
What I need:
COLOR=X AND ( title = Y OR description = Z)
What I tried (but it is malformed):
{
"query": {
"bool": {
"filter": [
{
"term": {
"colors.source_name": "braun"
}
},
{
"should": [
{
"term": {
"title": "sofa"
}
},
{
"term": {
"description": "sofa"
}
}
]
}
]
}
}
What I also tried, but it also provided results without "gartenlounge", and especially with scoring:
{
"query": {
"bool": {
"filter": [
{
"term": {
"colors.source_name": "braun"
}
}
],
"should": [
{
"term": {
"title": "sofa"
}
},
{
"term": {
"description": "sofa"
}
}
]
}
}
The following query should work for you:
{
"query": {
"bool": {
"filter": [
{"term": {
"colors.source_name": "braun"
}},
{"bool": {
"should": [
{"term": {"title": "sofa"}},
{"term": {"description": "sofa"}}
]
}}
]
}
}
}
You can nest a bool query inside the filter context, and should is only valid from within a bool clause.
It's an old reference sir, but it still checks out:
https://www.elastic.co/guide/en/elasticsearch/guide/current/combining-filters.html

How to combine multiple bool queries in elasticsearch

I want to create the equivalent of the following query -
(city = 'New York' AND state = 'NY') AND ((businessName='Java' and businessName='Shop') OR (category='Java' and category = 'Shop'))
I tried different combinations of bool queries using must and should but nothing seems to be working. Can this be done?
How about something like this:
{
"query": {
"match_all": {}
},
"filter": {
"bool": {
"must": [
{
"term": {
"city": "New york"
}
},
{
"term": {
"state": "NY"
}
},
{
"bool": {
"should": [
{
"bool": {
"must": [
{
"term": {
"businessName": "Java"
}
},
{
"term": {
"businessName": "Shop"
}
}
]
}
},
{
"bool": {
"must": [
{
"term": {
"category": "Java"
}
},
{
"term": {
"category": "Shop"
}
}
]
}
}
]
}
}
]
}
}
}

Resources