question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Issues With Filter Clause Inside Bool Query

See original GitHub issue

As far a I can see, since ElasticSearch 2.x and above - there shouldn’t be any difference between the structure of “Must” and “Filter” clauses inside bool queries. However, there is a difference in bodybuilder. I have added an explanation below.

I believe the issues are leftovers from previous bodybuilder versions supporting ElasticSearch 1.x. What do you think?

MUST

Single must:

bodybuilder()
		.query('term','user','Idan')
  		.build()

result as expected by bodybuilder:

{
  "query": {
    "term": {
      "user": "Idan"
    }
  }
}

Multiple musts:

bodybuilder()
		.query('term','user','Idan')
		.query('term','level','INFO')
  		.build()

result as expected by bodybuilder. An ordinary array.

{
  "query": {
    "bool": {
      "must": [
        {
          "term": {
            "user": "Idan"
          }
        },
        {
          "term": {
            "level": "INFO"
          }
        }
      ]
    }
  }
}

FILTER

Single filter:

bodybuilder()
		.filter('term','user','Idan')
  		.build()

Result as expected by bodybuilder. It might look unnecessary to wrap the clause with bool since it is only a single clause, however this way will make sure no score will be calculated (“Filter context is in effect whenever a query clause is passed to a filter parameter, such as the filter or must_not parameters in the bool query, the filter parameter in the constant_score query, or the filter aggregation”).

{
  "query": {
    "bool": {
      "filter": {
        "term": {
          "user": "Idan"
        }
      }
    }
  }
}

Multiple filters:

bodybuilder()
   	        .filter('term','user','Idan')
		.filter('term','level','INFO')
  		.build()

Unexpected result by bodybuilder. Why wrapping the clauses with bool and must, instead of an ordinary array?

{
  "query": {
    "bool": {
      "filter": {
        "bool": {
          "must": [
            {
              "term": {
                "user": "Idan"
              }
            },
            {
              "term": {
                "level": "INFO"
              }
            }
          ]
        }
      }
    }
  }
}

Issue Analytics

  • State:closed
  • Created 7 years ago
  • Comments:16 (2 by maintainers)

github_iconTop GitHub Comments

3reactions
cperrykcommented, Jul 7, 2017

To elaborate, consider this:

bodybuilder()
  .filter('term', 'foo')
  .filter('term', 'bar')
  .build()

Which produces this:

{
  "query": {
    "bool": {
      "filter": {
        "bool": {
          "must": [
            {
              "term": {
                "field": "foo"
              }
            },
            {
              "term": {
                "field": "bar"
              }
            }
          ]
        }
      }
    }
  }
}

I’m not wondering why that JS turns two filter calls into a separate bool query – that makes sense if we need to chain it with other clauses at that first level – I’m wondering why that new bool query uses a must instead of a filter clause. Why doesn’t the above JS produce this instead?

{
  "query": {
    "bool": {
      "filter": {
        "bool": {
          "filter": [ // <-- filter
            {
              "term": {
                "field": "foo"
              }
            },
            {
              "term": {
                "field": "bar"
              }
            }
          ]
        }
      }
    }
  }
}
1reaction
johannes-scharlachcommented, Apr 10, 2018

I understand the elasticsearch docs so that the query is executed in filter context once filter context is initiated https://www.elastic.co/guide/en/elasticsearch/reference/current/query-filter-context.html

In other words: once you’re in filter context, you can’t execute a a query in query context anymore.

Do you have any example or docs that show that those two are different? In that case is be happy to reopen and address this asap

Read more comments on GitHub >

github_iconTop Results From Across the Web

Boolean query | Elasticsearch Guide [8.5] | Elastic
Clauses are executed in filter context meaning that scoring is ignored and clauses are considered for caching. Because scoring is ignored, a score...
Read more >
Elasticsearch Bool Query - Filter, Must, Should & Must Not ...
All conditions are mandatory: Elasticsearch will return only documents that match all the clauses. However the score will not be computed. The filter...
Read more >
Elasticsearch boolean query doesn't work with filter
As for why ins doesn't work, it depends on your mapping + analyzer being used. You are matching against analyzed terms in the...
Read more >
Elasticsearch Bool Queries: How the Filter Query Improves ...
The filter query improves search performance because filtered queries are automatically stored in memory for fast retrieval. We also provide ...
Read more >
Boolean Queries - Open Distro for Elasticsearch
A query within a filter clause is a yes-no option, where if a document matches the query it's included in the results. Otherwise,...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found