[[search-request-post-filter]]
=== Post filter

The `post_filter` is applied to the search `hits` at the very end of a search
request,  after aggregations have already been calculated. It's purpose is
best explained by example:

Imagine that you are selling shirts, and the 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 
<<query-dsl-filtered-query,`filtered` query>>:

[source,json]
--------------------------------------------------
curl -XGET localhost:9200/shirts/_search -d '
{
  "query": {
    "filtered": {
      "filter": {
        "bool": {
          "must": [
            { "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 
<<search-aggregations-bucket-terms-aggregation,`terms` aggregation>>:

[source,json]
--------------------------------------------------
curl -XGET localhost:9200/shirts/_search -d '
{
  "query": {
    "filtered": {
      "filter": {
        "bool": {
          "must": [
            { "term": { "color": "red"   }},
            { "term": { "brand": "gucci" }}
          ]
        }
      }
    }
  },
  "aggs": {
    "models": {
      "terms": { "field": "model" } <1>
    }
  }
}
'
--------------------------------------------------
<1> Returns the most popular models of red shirts by Gucci.

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`:

[source,json]
--------------------------------------------------
curl -XGET localhost:9200/shirts/_search -d '
{
  "query": {
    "filtered": {
      "filter": {
        { "term": { "brand": "gucci" }} <1>
      }
    }
  },
  "aggs": {
    "colors": {
      "terms": { "field": "color" }, <2>
    },
    "color_red": {
      "filter": {
        "term": { "color": "red" } <3>
      },
      "aggs": {
        "models": {
          "terms": { "field": "model" } <3>
        }
      }
    }
  },
  "post_filter": { <4>
    "term": { "color": "red" }
  }
}
'
--------------------------------------------------
<1> The main query now finds all shirts by Gucci, regardless of color.
<2> The `colors` agg returns popular colors for shirts by Gucci.
<3> The `color_red` agg limits the `models` sub-aggregation 
    to *red* Gucci shirts.
<4> Finally, the `post_filter` removes colors other than red
    from the search `hits`.

