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
GET /tutorials/_search
{
"query": {
"bool": {
"must": [
{ "match": { "body": "redis" } }
],
"filter": [
{ "term": { "difficulty": "beginner" } },
{ "range": { "publishedAt": { "gte": "2026-01-01" } } }
]
}
}
}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 Query — Elastic