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
booleanquery filter clauses to filter search hits and aggregations, such as to narrow results to specific categories or brands. - Post-filter filtering: Use
post_filterto 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
electronicsand 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
electronicsindex using the following request:
POST /_bulk?refresh
{ "index": { "_index": "electronics", "_id": "1" } }
{ "brand": "BrandA", "category": "Smartphone", "price": 699.99, "features": ["5G", "Dual Camera"] }
{ "index": { "_index": "electronics", "_id": "2" } }
{ "brand": "BrandA", "category": "Laptop", "price": 1199.99, "features": ["Touchscreen", "16GB RAM"] }
{ "index": { "_index": "electronics", "_id": "3" } }
{ "brand": "BrandB", "category": "Smartphone", "price": 799.99, "features": ["5G", "Triple Camera"] }
- Apply a
booleanfilter query to display onlysmartphonesfromBrandAusing 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 }
]
}
}
}
}
}
}