[[query-filter-context]]
== Query and filter context

[discrete]
[[relevance-scores]]
=== Relevance scores

By default, Elasticsearch sorts matching search results by **relevance
score**, which measures how well each document matches a query.

The relevance score is a positive floating point number, returned in the
`_score` metadata field of the <<search-request-body,search>> API. The higher the
`_score`, the more relevant the document. While each query type can calculate
relevance scores differently, score calculation also depends on whether the
query clause is run in a **query** or **filter** context.

[discrete]
[[query-context]]
=== Query context
In the query context, a query clause answers the question ``__How well does this
document match this query clause?__'' Besides deciding whether or not the
document matches, the query clause also calculates a relevance score in the
`_score` metadata field.

Query context is in effect whenever a query clause is passed to a `query`
parameter, such as the `query` parameter in the
<<request-body-search-query,search>> API.

[discrete]
[[filter-context]]
=== Filter context
In a filter context, a query clause answers the question ``__Does this
document match this query clause?__''  The answer is a simple Yes or No -- no
scores are calculated. Filter context is mostly used for filtering structured
data, e.g.

*  __Does this +timestamp+ fall into the range 2015 to 2016?__
*  __Is the +status+  field set to ++"published"++__?

Frequently used filters will be cached automatically by Elasticsearch, to
speed up performance.

Filter context is in effect whenever a query clause is passed to a `filter`
parameter, such as the `filter` or `must_not` parameters in the
<<query-dsl-bool-query,`bool`>> query, the `filter` parameter in the
<<query-dsl-constant-score-query,`constant_score`>> query, or the
<<search-aggregations-bucket-filter-aggregation,`filter`>> aggregation.

[discrete]
[[query-filter-context-ex]]
=== Example of query and filter contexts
Below is an example of query clauses being used in query and filter context
in the `search` API. This query will match documents where all of the following
conditions are met:

* The `title` field contains the word `search`.
* The `content` field contains the word `elasticsearch`.
* The `status` field contains the exact word `published`.
* The `publish_date` field contains a date from 1 Jan 2015 onwards.

[source,console]
------------------------------------
GET /_search
{
  "query": { <1>
    "bool": { <2>
      "must": [
        { "match": { "title":   "Search"        }},
        { "match": { "content": "Elasticsearch" }}  
      ],
      "filter": [ <3>
        { "term":  { "status": "published" }}, 
        { "range": { "publish_date": { "gte": "2015-01-01" }}} 
      ]
    }
  }
}
------------------------------------

<1> The `query` parameter indicates query context.
<2> The `bool` and two `match` clauses are used in query context,
    which means that they are used to score how well each document
    matches.
<3> The `filter` parameter indicates filter context. Its `term` and 
    `range` clauses are used in filter context. They will filter out 
    documents which do not match, but they will
    not affect the score for matching documents.

WARNING: Scores calculated for queries in query context are represented 
as single precision floating point numbers; they have only
24 bits for significand's precision. Score calculations that exceed the
significand's precision will be converted to floats with loss of precision.

TIP: Use query clauses in query context for conditions which should affect the
score of matching documents (i.e. how well does the document match), and use
all other query clauses in filter context.