[[function-score-filters]] === Boosting Filtered Subsets
Let's return to the problem that we were dealing with in <function_score
query we can do
just that.((("function_score query", "boosting filtered subsets")))
The examples we have shown thus far have used a single function for all documents. Now we want to divide the results into subsets by using filters (one filter per feature), and apply a different function to each subset.
The function that we will use in this example is ((("weight function")))the weight
, which is
similar to the boost
parameter accepted by any query. The difference is
that the weight
is not normalized by Lucene into some obscure floating-point
number; it is used as is.
The structure of the query has to change somewhat to incorporate multiple functions:
[source,json]
GET /_search { "query": { "function_score": { "filter": { <1> "term": { "city": "Barcelona" } }, "functions": [ <2> { "filter": { "term": { "features": "wifi" }}, <3> "weight": 1 }, { "filter": { "term": { "features": "garden" }}, <3> "weight": 1 }, { "filter": { "term": { "features": "pool" }}, <3> "weight": 2 <4> } ], "score_mode": "sum", <5> } }5>4>3>3>3>2>1>
}
<1> This function_score
query has a filter
instead of a query
.1>
<2> The functions
key holds a list of functions that should be applied.2>
<3> The function is applied only if the document matches the (optional) filter
.3>
<4> The pool
feature is more important than the others so it has a higher weight
.4>
<5> The score_mode
specifies how the values from each function should be combined.5>
The new features to note in this example are explained in the following sections.
==== filter Versus query
The first thing to note is that we have specified a filter
instead ((("filters", "in function_score query")))of a
query
. In this example, we do not need full-text search. We just want to
return all documents that have Barcelona
in the city
field, logic that is
better expressed as a filter instead of a query. All documents returned by
the filter will have a _score
of 1
. The function_score
query accepts
either a query
or a filter
. If neither is specified, it will default to
using the match_all
query.
==== functions
The functions
key holds an array of functions to apply.((("function_score query", "functions key"))) Each entry in the
array may also optionally specify a filter
, in which case the function will be applied only to documents that match that filter. In this example, we
apply a weight
of 1
(or 2
in the case of pool
) to any document
that matches the filter.
==== score_mode
Each function returns a result, and we need a way of reducing these multiple
results to a single value that can be combined with the original _score
.
This is the role ((("function_score query", "score_mode parameter")))((("score_mode parameter")))of the score_mode
parameter, which accepts the following
values:
multiply
::
Function results are multiplied together (default).
sum
::
Function results are added up.
avg
::
The average of all the function results.
max
::
The highest function result is used.
min
::
The lowest function result is used.
first
::
Uses only the result from the first function that either doesn't have a filter or that has a filter matching the document.
In this case, we want to add the weight
results from each matching
filter together to produce the final score, so we have used the sum
score
mode.
Documents that don't match any of the filters will keep their original
_score
of 1
.