elasticsearch/elasticsearch — pull request #5519 by dakrone (2014-03-24 16:15:27+00:00)
Title: Add the `field_value_factor` function to the function_score query

The `field_value_factor` function uses the value of a field in the document to influence the score. This is a common case that script scoring was previously used for.

For example, a query that looks like:

```json
{
"query": {
"function_score": {
"query": {"match": { "body": "foo" }},
"functions": [
{
"field_value_factor": {
"field": "popularity",
"factor": 1.1,
"modifier": "square"
}
}
],
"score_mode": "max",
"boost_mode": "sum"
}
}
}
```

Would have the score modified for each document by:

```
_score * square(1.1 * doc['popularity'])
```

This is faster and less error-prone than using scripting to influence the score. Speed-wise, I used the IMDB movie database and tested with two different queries:

```json
{
"query": {
"function_score": {
"query": {"match_all": {}},
"functions": [
{
"field_value_factor": {
"field": "runtime",
"modifier": "none",
"lenient": true
}
}
],
"score_mode": "max",
"boost_mode": "sum"
}
}
}
```

vs:

```json
{
"query": {
"function_score": {
"query": {"match_all": {}},
"functions": [
{
"script_score": {
"script": "_score * doc['runtime'].value"
}
}
],
"score_mode": "max",
"boost_mode": "sum"
}
}
}
```

The `field_value_factor` version took about 75ms on average, the `script_score` version took about 145ms on average (after field data was loaded for both versions). This doesn't include any error handling that `script_score` would have to provide (such as missing values) that the `field_value_factor` function provides with the lenient flag.