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": {
"item": {
"properties": {
"brand": { "type": "keyword"},
"color": { "type": "keyword"},
"model": { "type": "keyword"}
}
}
}
}
PUT /shirts/item/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" }
}
}