| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303 | [[query-dsl-script-score-query]]=== Script Score Queryexperimental[]The `script_score` allows you to modify the score of documents that areretrieved by a query. This can be useful if, for example, a scorefunction is computationally expensive and it is sufficient to computethe score on a filtered set of documents.To use `script_score`, you have to define a query and a script -a function to be used to compute a new score for each document returnedby the query. For more information on scripting see<<modules-scripting, scripting documentation>>.Here is an example of using `script_score` to assign each matched documenta score equal to the number of likes divided by 10:[source,js]--------------------------------------------------GET /_search{    "query" : {        "script_score" : {            "query" : {                "match": { "message": "elasticsearch" }            },            "script" : {                "source" : "doc['likes'].value / 10 "            }        }     }}--------------------------------------------------// CONSOLE// TEST[setup:twitter]==== Accessing the score of a document within a scriptWithin a script, you can<<modules-scripting-fields#scripting-score, access>>the `_score` variable which represents the current relevance score of adocument.==== Predefined functions within a Painless scriptYou can use any of the available<<painless-api-reference, painless functions>> in the painless script.Besides these functions, there are a number of predefined functionsthat can help you with scoring. We suggest you to use them instead ofrewriting equivalent functions of your own, as these functions tryto be the most efficient by using the internal mechanisms.===== rationallatexmath:[rational(value,k) = value/(k + value)][source,js]--------------------------------------------------"script" : {    "source" : "rational(doc['likes'].value, 1)"}--------------------------------------------------// NOTCONSOLE===== sigmoidlatexmath:[sigmoid(value, k, a) = value^a/ (k^a + value^a)][source,js]--------------------------------------------------"script" : {    "source" : "sigmoid(doc['likes'].value, 2, 1)"}--------------------------------------------------// NOTCONSOLE[[random-functions]]===== Random functionsThere are two predefined ways to produce random values:1. `randomNotReproducible()` uses `java.util.Random` classto generate a random value of the type `long`.The generated values are not reproducible between requests' invocations.    [source,js]    --------------------------------------------------    "script" : {        "source" : "randomNotReproducible()"    }    --------------------------------------------------    // NOTCONSOLE2. `randomReproducible(String seedValue, int seed)` producesreproducible random values of type `long`. This function requiresmore computational time and memory than the non-reproducible version.A good candidate for the `seedValue` is document field values thatare unique across documents and already pre-calculated and preloadedin the memory. For example, values of the document's `_seq_no` fieldis a good candidate, as documents on the same shard have unique valuesfor the `_seq_no` field.    [source,js]    --------------------------------------------------    "script" : {        "source" : "randomReproducible(Long.toString(doc['_seq_no'].value), 100)"    }    --------------------------------------------------    // NOTCONSOLEA drawback of using `_seq_no` is that generated values change ifdocuments are updated. Another drawback is not absolute uniqueness, asdocuments from different shards with the same sequence numbersgenerate the same random values.If you need random values to be distinct across different shards,you can use a field with unique values across shards,such as  `_id`, but watch out for the memory usage as allthese unique values need to be loaded into memory.    [source,js]    --------------------------------------------------    "script" : {        "source" : "randomReproducible(doc['_id'].value, 100)"    }    --------------------------------------------------    // NOTCONSOLE[[decay-functions]]===== Decay functions for numeric fieldsYou can read more about decay functions<<query-dsl-function-score-query#function-decay, here>>.* `double decayNumericLinear(double origin, double scale, double offset, double decay, double docValue)`* `double decayNumericExp(double origin, double scale, double offset, double decay, double docValue)`* `double decayNumericGauss(double origin, double scale, double offset, double decay, double docValue)`[source,js]--------------------------------------------------"script" : {    "source" : "decayNumericLinear(params.origin, params.scale, params.offset, params.decay, doc['dval'].value)",    "params": { <1>        "origin": 20,        "scale": 10,        "decay" : 0.5,        "offset" : 0    }}--------------------------------------------------// NOTCONSOLE<1> Use `params` to compile a script only once for different values of parameters===== Decay functions for geo fields* `double decayGeoLinear(String originStr, String scaleStr, String offsetStr, double decay, GeoPoint docValue)`* `double decayGeoExp(String originStr, String scaleStr, String offsetStr, double decay, GeoPoint docValue)`* `double decayGeoGauss(String originStr, String scaleStr, String offsetStr, double decay, GeoPoint docValue)`[source,js]--------------------------------------------------"script" : {    "source" : "decayGeoExp(params.origin, params.scale, params.offset, params.decay, doc['location'].value)",    "params": {        "origin": "40, -70.12",        "scale": "200km",        "offset": "0km",        "decay" : 0.2    }}--------------------------------------------------// NOTCONSOLE===== Decay functions for date fields* `double decayDateLinear(String originStr, String scaleStr, String offsetStr, double decay, JodaCompatibleZonedDateTime docValueDate)`* `double decayDateExp(String originStr, String scaleStr, String offsetStr, double decay, JodaCompatibleZonedDateTime docValueDate)`* `double decayDateGauss(String originStr, String scaleStr, String offsetStr, double decay, JodaCompatibleZonedDateTime docValueDate)`[source,js]--------------------------------------------------"script" : {    "source" : "decayDateGauss(params.origin, params.scale, params.offset, params.decay, doc['date'].value)",    "params": {        "origin": "2008-01-01T01:00:00Z",        "scale": "1h",        "offset" : "0",        "decay" : 0.5    }}--------------------------------------------------// NOTCONSOLENOTE: Decay functions on dates are limited to dates in the default formatand default time zone. Also calculations with `now` are not supported.==== Faster alternativesScript Score Query calculates the score for every hit (matching document).There are faster alternative query types that can efficiently skipnon-competitive hits:* If you want to boost documents on some static fields, use <<query-dsl-feature-query, Feature Query>>.==== Transition from Function Score QueryWe are deprecating <<query-dsl-function-score-query, Function Score>>, andScript Score Query will be a substitute for it.Here we describe how Function Score Query's functions can beequivalently implemented in Script Score Query:===== `script_score`What you used in `script_score` of the Function Score query, youcan copy into the Script Score query. No changes here.===== `weight``weight` function can be implemented in the Script Score query throughthe following script:[source,js]--------------------------------------------------"script" : {    "source" : "params.weight * _score",    "params": {        "weight": 2    }}--------------------------------------------------// NOTCONSOLE===== `random_score`Use `randomReproducible` and `randomNotReproducible` functionsas described in <<random-functions, random functions>>.===== `field_value_factor``field_value_factor` function can be easily implemented through script:[source,js]--------------------------------------------------"script" : {    "source" : "Math.log10(doc['field'].value * params.factor)",    params" : {        "factor" : 5    }}--------------------------------------------------// NOTCONSOLEFor checking if a document has a missing value, you can use`doc['field'].size() == 0`. For example, this script will usea value `1` if a document doesn't have a field `field`:[source,js]--------------------------------------------------"script" : {    "source" : "Math.log10((doc['field'].size() == 0 ? 1 : doc['field'].value()) * params.factor)",    params" : {        "factor" : 5    }}--------------------------------------------------// NOTCONSOLEThis table lists how `field_value_factor` modifiers can be implementedthrough a script:[cols="<,<",options="header",]|=======================================================================| Modifier | Implementation in Script Score| `none` | -| `log` |  `Math.log10(doc['f'].value)`| `log1p` | `Math.log10(doc['f'].value + 1)`| `log2p` | `Math.log10(doc['f'].value + 2)`| `ln` | `Math.log(doc['f'].value)`| `ln1p` | `Math.log(doc['f'].value + 1)`| `ln2p` | `Math.log(doc['f'].value + 2)`| `square` | `Math.pow(doc['f'].value, 2)`| `sqrt` | `Math.sqrt(doc['f'].value)`| `reciprocal` | `1.0 / doc['f'].value`|============================================================================ `decay functions`Script Score query has equivalent <<decay-functions, decay functions>>that can be used in script.
 |