Elasticsearch Filter and Bool Queries
Real search features rarely run a single query. Most require combining conditions — "find laptops under ₹50,000 that are in stock and rated above 4 stars." The bool query is how you do that in Elasticsearch.
The Bool Query — Four Clauses
+-----------+--------------------------------------------------+ | Clause | Meaning | +-----------+--------------------------------------------------+ | must | Document MUST match — affects relevance score | | filter | Document MUST match — does NOT affect score | | should | Document SHOULD match — boosts score if it does | | must_not | Document MUST NOT match | +-----------+--------------------------------------------------+
Combine any number of clauses to build complex logic with full control over scoring.
must vs filter — The Key Difference
User searches for: "wireless headphones under ₹3000" must clause (matches + scores): "wireless headphones" in name → score matters Elasticsearch ranks by how relevant the text match is filter clause (matches but no score): price < 3000 → either yes or no There is no "how much under ₹3000" — it does not affect score Elasticsearch CACHES this result for speed
Put text searches in must and put numeric ranges, dates, and exact values in filter. This gives you both relevance ranking and fast cached filtering.
Basic Bool Query Example
GET /products/_search
{
"query": {
"bool": {
"must": [
{ "match": { "name": "wireless headphones" } }
],
"filter": [
{ "term": { "category": "electronics" } },
{ "range": { "price": { "lte": 3000 } } },
{ "term": { "in_stock": true } }
]
}
}
}
This finds electronics that are in stock, cost ₹3000 or less, and match the text "wireless headphones." Relevance score comes only from the text match.
Adding should — Bonus Matching
Documents matching a should clause score higher but are not excluded if they miss it.
GET /products/_search
{
"query": {
"bool": {
"must": [
{ "match": { "name": "headphones" } }
],
"should": [
{ "term": { "brand": "Sony" } },
{ "range": { "rating": { "gte": 4.5 } } }
],
"filter": [
{ "term": { "in_stock": true } }
]
}
}
}
Every in-stock headphone appears in results. Sony headphones and highly rated ones appear near the top because the should clauses add to their score.
must_not — Excluding Results
GET /products/_search
{
"query": {
"bool": {
"must": [
{ "match": { "name": "laptop" } }
],
"must_not": [
{ "term": { "brand": "UnknownBrand" } },
{ "range": { "price": { "gt": 100000 } } }
]
}
}
}
Laptops from UnknownBrand and any laptop over ₹1 lakh are excluded entirely.
minimum_should_match
Control how many should clauses must match for a document to appear in results:
GET /products/_search
{
"query": {
"bool": {
"should": [
{ "term": { "color": "black" } },
{ "term": { "brand": "Sony" } },
{ "range": { "rating": { "gte": 4 } } }
],
"minimum_should_match": 2
}
}
}
A document must satisfy at least 2 of the 3 should conditions to appear in results.
Nested Bool Queries
Bool queries nest inside other bool queries for complex logic — like building a sentence with parentheses:
Find: (Sony OR Bose) AND (under ₹5000 OR rated above 4.5)
GET /products/_search
{
"query": {
"bool": {
"must": [
{
"bool": {
"should": [
{ "term": { "brand": "Sony" } },
{ "term": { "brand": "Bose" } }
],
"minimum_should_match": 1
}
},
{
"bool": {
"should": [
{ "range": { "price": { "lte": 5000 } } },
{ "range": { "rating": { "gte": 4.5 } } }
],
"minimum_should_match": 1
}
}
]
}
}
}
Filter Context vs Query Context
Query Context (must, should): - Elasticsearch calculates a relevance score - Results are sorted by score (best match first) - Slower — scoring takes computation Filter Context (filter, must_not): - No relevance score calculated - Results are either in or out (binary) - Faster — results are cacheable - Best for: exact values, ranges, dates, booleans
Practical Tip: Always Filter First
Put all non-text conditions inside filter and only your actual search text inside must. This pattern makes Elasticsearch cache your filters, dramatically speeding up repeated similar queries — for example, when many users browse the same category with different search terms.
