Combining filter and must in elasticsearch - 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.

Related

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.

Complex Nested Query Where to Place Bool Match

I have a complex index within Elastic that I need to query by 3 parameters.
Thanks to this answered question I am able to query by 2 of the 3 parameters, however the 3rd parameter is not at the same nested level as the other two.
The schema looks this..
The following query works for the 2 of the 3 parameters...
But the 3rd parameter is at a different level the the other two so this query does not return the expected document.
Given that the bool match query for "boundedContexts.aggregateRoot.aggregateType.name" is at a different nested level, how would I write this query so that it will query on that field ?
This works...
{
"query": {
"nested": {
"path": "boundedContexts",
"query": {
"nested": {
"path": "boundedContexts.aggregateRoots",
"query": {
"bool": {
"must": [
{ "match": { "boundedContexts.aggregateRoots.aggregateType.name": "Aggregate" } },
{ "nested": {
"path": "boundedContexts.aggregateRoots.modelMetaData",
"query": {
"bool": {
"must": [
{ "match": { "boundedContexts.aggregateRoots.modelMetaData.modelReferenceId": "4e7c5c0e-93a7-4bf6-9705-cf1327760e21" } },
{ "match": { "boundedContexts.aggregateRoots.modelMetaData.modelType.name": "AggregateRoot" } }
]
}
}
}
}
]
}
}
}
}
}
},
"size": 1,
"sort": [
{
"generatedDate": {
"order": "desc"
}
}
]
}

Elasticsearch with nested AND/OR query

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"
}
}
]
}
}
]
}
}
}```

NOT condition in elasticsearch

I am trying to implement NOT condition in elasticsearch query.
Can I Implement filter inside bool or I need to write separate
filter as below. Any optimum solution is there?
{
"query": {
"bool": {
"must": [
{
"query_string": {
"query": "fashion"
}
},
{
"term": {
"post_status": "publish"
}
}
]
}
},
"filter": {
"not": {
"filter": {
"term": {
"post_type": "page"
}
}
}
}
}
You can use a must_not clause:
{
"query": {
"bool": {
"must": [
{
"match": {
"_all": "fashion"
}
},
{
"term": {
"post_status": "publish"
}
}
],
"must_not": {
"term": {
"post_type": "page"
}
}
}
}
}
Also, I'd recommend using a match filter instead of query_string, as query_string requires the much more strict Lucene syntax (and is therefor more error prone), whereas match works more like a search box: it will automatically transform a human readable query to a Lucene 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