Thuta Learning
IntermediateData & Databasesbeginner

Compound Queries — bool, must vs filter vs should

What you'll walk away with

  • Explain the core ideas behind Compound Queries — bool, must vs filter vs should
  • Run the sample Elasticsearch query or code and verify its output
  • Apply the technique correctly to the Tutorial Platform and production scenarios

Build the mental model

Real-world searches rarely have one criterion — you might need "redis" as a keyword AND `difficulty: beginner` AND `publishedAt` within 2026 all at once — and a `bool` query combines these compound conditions using four clause types: `must`, `filter`, `should`, and `must_not`. Queries inside `must` need to match and also contribute to the `_score` — put full-text search conditions that matter for relevance ranking here. Queries inside `filter` also need to match, but they never contribute to `_score` (no relevance calculation, just a binary yes/no decision), so Elasticsearch can internally cache filter clause results, meaning a repeated filter (like `status: published`) across many requests can be served instantly from memory without any scoring computation. `should` clauses are optional and can boost the score on a match (when `minimum_should_match` is not set). Think of it like a library reference desk: the librarian's relevance judgment about "which books are most related to this topic" belongs in the `must` clause, while "is it currently available" is a yes/no fact handled instantly as a checklist item in the `filter` clause — a checklist needs no judgment, so it's faster.

Connect it to a real scenario

In the Tutorial Platform's search filter UI, when a user types "redis" and checks the "Beginner" difficulty checkbox, combine them in one `bool` query: `must: [{ match: { body: "redis" } }]` alongside `filter: [{ term: { difficulty: "beginner" } }]` — treating keyword matching as relevance-based (`must`) and the difficulty selection as a binary criterion (`filter`) avoids unnecessary scoring cost. Putting the difficulty filter inside `must` instead would give the same correctness but worse performance, because Elasticsearch would compute a relevance score for the difficulty match too, losing the ability to cache it.

Try the working example

http
GET /tutorials/_search
{
  "query": {
    "bool": {
      "must": [
        { "match": { "body": "redis" } }
      ],
      "filter": [
        { "term": { "difficulty": "beginner" } },
        { "range": { "publishedAt": { "gte": "2026-01-01" } } }
      ]
    }
  }
}
You should see
You get a relevance-ranked list of tutorials containing "redis", with beginner difficulty, published in 2026.

5-minute try-it

Write a `bool` query searching for tutorials with the keyword "caching", tagged "redis", and not `difficulty: advanced` — use all three of `must`, `filter`, and `must_not`.

One important caution

Putting a binary criterion (status, category, exact ID) inside `must` instead of `filter` — correctness stays the same, but unnecessary relevance scoring hurts performance.

Using only `should` clauses with no `must` or `filter` present, assuming they are purely optional — by default at least one `should` clause must still match, which can silently mismatch the query's intended logic.

Elasticsearch Guide — Bool QueryElastic

Easy traps

  • Putting a binary criterion (status, category, exact ID) inside `must` instead of `filter` — correctness stays the same, but unnecessary relevance scoring hurts performance.
  • Using only `should` clauses with no `must` or `filter` present, assuming they are purely optional — by default at least one `should` clause must still match, which can silently mismatch the query's intended logic.
  • Validate sample queries and requests on a local or test instance with recoverable data before applying them to production.

Exercise

Write a `bool` query searching for tutorials with the keyword "caching", tagged "redis", and not `difficulty: advanced` — use all three of `must`, `filter`, and `must_not`.

You'll know it worked when: You get a relevance-ranked list of tutorials containing "redis", with beginner difficulty, published in 2026.

Compound Queries — bool, must vs filter vs should | Thuta Learning