Filter search results
You can filter searches using different methods, each suited to specific scenarios. You can apply filters at the query level, using boolean
query clauses and post_filter
and aggregation
level filters, as follows:
- Query-level filtering: Apply
boolean
query filter clauses to filter search hits and aggregations, such as to narrow results to specific categories or brands. - Post-filter filtering: Use
post_filter
to refine search hits based on user selections while preserving all aggregation options. - Aggregation-level filtering: Adjust specific aggregations based on selected filters without impacting other aggregations.
Query-level filtering with Boolean queries
Use a boolean
query with a filter clause to apply filters to both search hits and aggregations. For example, if a shopper searches for smartphones
from BrandA
, a Boolean query can restrict results to only those smartphones from BrandA
. The following steps guide you through query-level filtering.
- Create an index
electronics
and provide the mapping using the following request:
PUT /electronics
{
"mappings": {
"properties": {
"brand": { "type": "keyword" },
"category": { "type": "keyword" },
"price": { "type": "float" },
"features": { "type": "keyword" }
}
}
}
- Add documents to the
electronics
index using the following request:
PUT /electronics/_doc/1?refresh
{
"brand": "BrandA",
"category": "Smartphone",
"price": 699.99,
"features": ["5G", "Dual Camera"]
}
PUT /electronics/_doc/2?refresh
{
"brand": "BrandA",
"category": "Laptop",
"price": 1199.99,
"features": ["Touchscreen", "16GB RAM"]
}
PUT /electronics/_doc/3?refresh
{
"brand": "BrandB",
"category": "Smartphone",
"price": 799.99,
"features": ["5G", "Triple Camera"]
}
- Apply a
boolean
filter query to display onlysmartphones
fromBrandA
using the following request:
GET /electronics/_search
{
"query": {
"bool": {
"filter": [
{ "term": { "brand": "BrandA" }},
{ "term": { "category": "Smartphone" }}
]
}
}
}
Narrowing results using post-filter
while preserving aggregation visibility
Use post_filter
to limit search hits while preserving all aggregation options. For example, if a shopper selects BrandA
, results are filtered to show only BrandA
products while maintaining the visibility of all brand options in the aggregations, as shown in the following example request:
GET /electronics/_search
{
"query": {
"bool": {
"filter": { "term": { "category": "Smartphone" }}
}
},
"aggs": {
"brands": {
"terms": { "field": "brand" }
}
},
"post_filter": {
"term": { "brand": "BrandA" }
}
}
The result should show BrandA
smartphones in the search hits and all brands in the aggregations.
Refining aggregations with aggregation-level filtering
You can use aggregation-level filtering to apply filters to specific aggregations without affecting the main aggregation to which they belong.
For example, you can use aggregation-level filtering to filter the price_ranges
aggregation based on selected brands, BrandA
and BrandB
, without affecting the main price_ranges
aggregation, as shown in the following example request. This displays price ranges relevant to the selected brands while also displaying overall price ranges for all products.
GET /electronics/_search
{
"query": {
"bool": {
"filter": { "term": { "category": "Smartphone" }}
}
},
"aggs": {
"price_ranges": {
"range": {
"field": "price",
"ranges": [
{ "to": 500 },
{ "from": 500, "to": 1000 },
{ "from": 1000 }
]
}
},
"filtered_brands": {
"filter": {
"terms": { "brand": ["BrandA", "BrandB"] }
},
"aggs": {
"price_ranges": {
"range": {
"field": "price",
"ranges": [
{ "to": 500 },
{ "from": 500, "to": 1000 },
{ "from": 1000 }
]
}
}
}
}
}
}