Elasticsearch with nested AND/OR query - elasticsearch

I'm struggling with writing an elastic search query with multiple AND/OR conditions.
It basically comes to the following logic:
cond1 && (cond2 || cond3 || cond4)
As mentioned in the docs, a document is considered a match if it satisfies only the must clause. The should clauses in this case act as a boost i.e. if a document matches one or more of the should clauses in addition to the must clause, then it will have a higher relevancy score, assuming that cond2, cond3 and cond4 are queries that calculate a relevancy score.
The problem is that I only want documents that also match at least one of the OR conditions.
Note that I'm running ES6.3. I've also tried Multiword queries but these results are also wrong.
Adding boost doesn't seem to affect the results, I have results that only match the first condition.
{
"query": {
"bool": {
"must": [
{
"term": {
"event.keyword": {
"value": "webhook.trigger"
}
}
}
],
"should": [
{
"match": {
"metaData.webhook.title": "My Example Title 1"
}
},
{
"match": {
"metaData.webhook.title": "Testing"
}
},
{
"match": {
"metaData.webhook.url": "myurl.com"
}
}
]
}
}
}

A should query works like a OR only if there is not a must query. In your case you should wrap the should query in another bool query.
{
"query": {
"bool": {
"must": [
{
"term": {
"event.keyword": {
"value": "webhook.trigger"
}
}
},
{
"bool": {
"should": [
{
"match": {
"metaData.webhook.title": "My Example Title 1"
}
},
{
"match": {
"metaData.webhook.title": "Testing"
}
},
{
"match": {
"metaData.webhook.url": "myurl.com"
}
}
]
}
}
]
}
}
}```

Related

How to filter result set of elasticsearch from another bool condition

I have to fetch data from API which use ElasticSearch.
The conditions of data fetching are firstname should start with given string and company status should be active,
so I have used the below query
"span_first": {
"match": {
"span_term": {
"employee.firstname": "tas"
}
},
"end": 1
}
to match firstname and now i need to filter the data from companyStatus,
"bool": {
"must": [
{
"match": {
"employee.companyStatus": "Active"
}
}
]
}
I'm trying to plug the above bool query into the span_first query
but I have no idea how to do it,
Can someone help me to create the query, sorry if this is a dumb question,
I'm totally new to Elasticsearch.
You can try to use Term Query for filter status and Match Query for search terms.
GET edx_test/_search
{
"query": {
"bool": {
"filter": [
{
"term": {
"employee.companyStatus": "Active"
}
}
],
"must": [
{
"match": {
"employee.firstname": "tas"
}
}
]
}
}
}
Read more:
https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-term-query.html
https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-bool-query.html
If both the span_first and match query must be true then you can have both the queries in a must clause like below:
GET test_index/_search
{
"query": {
"bool": {
"must": [
{
"match": {
"employee.companyStatus": "Active"
}
},
{
"span_first": {
"match": {
"span_term": {
"employee.firstname": "tas"
}
},
"end": 1
}
}
]
}
}
}

Elasticsearch search query: nested query with OR-gates & AND-gates

I have docs as follow:
{
"name": "...",
"country": "...",
}
I need to find. either one of the following criteria:
name=John AND country=US
name=Andy AND country=UK
How should be write this nested query?
Assuming the default fields mapping is defined, you can use boolean queries as follows:
{
"query": {
"bool": {
"should": [
{
"bool": {
"filter": [
{
"term": {
"name.keyword": "John"
}
},
{
"term": {
"country.keyword": "US"
}
}
]
}
},
{
"bool": {
"filter": [
{
"term": {
"name.keyword": "Andy"
}
},
{
"term": {
"country.keyword": "UK"
}
}
]
}
}
]
}
}
}
You should use must instead of filter if you want the query to contribute to the score.
must
The clause (query) must appear in matching documents and will
contribute to the score.
filter
The clause (query) must appear in matching documents. However unlike
must the score of the query will be ignored. Filter clauses are
executed in filter context, meaning that scoring is ignored and
clauses are considered for caching.

Combining filter and must in elasticsearch

What is the difference between adding a query filter inside a must and having a query filter and a must separately?
I need to apply a filter query to a search for but either of these two queries works the same for me. I would like to know if there are any differences.
Case 1:
"query": {
"bool": {
"must": [
{
"term": {
"field": {
"value": "VALUE"
}
}
},
{
"bool": {
"filter": [
{
"script": {
"script": {
"source": """
return true;
"""
}
}
}
]
}
}
]
}
}
Case 2:
"query": {
"bool": {
"must": [
{
"term": {
"field": {
"value": "VALUE"
}
}
}
],
"filter": [
{
"script": {
"script": {
"source": """
return true;
"""
}
}
}
]
}
}
In my opinion they do not differ, but I need references. Greetings.
Both the query will work exactly the same
Refer to documentation on the boolean query to know more about your structure
must: The clause (query) must appear in matching documents and will
contribute to the score.
filter: The clause (query) must appear in matching documents. However
unlike must the score of the query will be ignored. Filter clauses are
executed in filter context, meaning that scoring is ignored and
clauses are considered for caching.
Structure of your first query where multiple bool queries are combined:
{
"query": {
"bool": {
"must": [
{
"term": {},
"bool": {
"filter": {
"script": {}
}
}
}
]
}
}
}
Structure of your second query that includes single bool query:
{
"query": {
"bool": {
"must": [
{
"term": {}
}
],
"filter": [
{
"script": {}
}
]
}
}
}
As you can see, in both the search queries the document will match only when both the term query and script query condition is satisfied
They both will work exactly the same, second one would be preferred syntax because it's not as nested as first one and easier to read.

Equivalent of boolean or in ElasticSearch

I currently search my data for exact matches on one term like this:
{
"query": {
"bool": {
"must": [
{
"term": {
"term_a": "xxxxx"
}
}
]
}
}
}
However, I want to be able to search on multiple terms and get all documents that match at least one. So in SQL speak term_a = 'xxxxx' or term_b = 'yyyyy'. How can I do this?
Then you can use a bool with should statements for each term:
"bool": {
"should": [
{
"term": {
"term_a": "xxxxx"
}
},
{
"term": {
"term_b": "yyyyy"
}
}
]
}
If you want to search multiple terms in the same field then you can use a terms query.

Using term query with Or operator

I am trying to use the term query the following way!!
{
"query": {
"bool": {
"must": [
{
"term": {
"technology": "Space"
}
},
{
"term": {
"Person": "Steve Simon"
}
}
]
}
}
}
Which returns me a response of feeds which has both fields present in single feed like an intersection operation. Can I use the term query to get UNION result for the above query like, I want all feeds which has space, Steve Simon present individually with feeds which has both present.
Use should instead of must. Also you have to set minimum_should_match to 1 which means that only one should clause is needed for matching a document.
{
"query": {
"bool": {
"should": [
{
"term": {
"technology": "Space"
}
},
{
"term": {
"Person": "Steve Simon"
}
}
],
"minimum_should_match": 1
}
}
}

Resources