Post filter
editPost filter
editThe post_filter
is applied to the search hits
at the very end of a search
request, after aggregations have already been calculated. Its purpose is
best explained by example:
Imagine that you are selling shirts that have the following properties:
PUT /shirts { "mappings": { "properties": { "brand": { "type": "keyword"}, "color": { "type": "keyword"}, "model": { "type": "keyword"} } } } PUT /shirts/_doc/1?refresh { "brand": "gucci", "color": "red", "model": "slim" }
Imagine a user has specified two filters:
color:red
and brand:gucci
. You only want to show them red shirts made by
Gucci in the search results. Normally you would do this with a
bool
query:
GET /shirts/_search { "query": { "bool": { "filter": [ { "term": { "color": "red" }}, { "term": { "brand": "gucci" }} ] } } }
However, you would also like to use faceted navigation to display a list of
other options that the user could click on. Perhaps you have a model
field
that would allow the user to limit their search results to red Gucci
t-shirts
or dress-shirts
.
This can be done with a
terms
aggregation:
GET /shirts/_search { "query": { "bool": { "filter": [ { "term": { "color": "red" }}, { "term": { "brand": "gucci" }} ] } }, "aggs": { "models": { "terms": { "field": "model" } } } }
But perhaps you would also like to tell the user how many Gucci shirts are
available in other colors. If you just add a terms
aggregation on the
color
field, you will only get back the color red
, because your query
returns only red shirts by Gucci.
Instead, you want to include shirts of all colors during aggregation, then
apply the colors
filter only to the search results. This is the purpose of
the post_filter
:
GET /shirts/_search { "query": { "bool": { "filter": { "term": { "brand": "gucci" } } } }, "aggs": { "colors": { "terms": { "field": "color" } }, "color_red": { "filter": { "term": { "color": "red" } }, "aggs": { "models": { "terms": { "field": "model" } } } } }, "post_filter": { "term": { "color": "red" } } }