elasticsearch/elasticsearch — pull request #3308 by brwe (2013-07-09 16:45:46+00:00)
Title: Distance scoring

================

It might sometimes be desirable to have a tool available that allows to multiply the original score for a document with a function that decays depending on the distance of a numeric field value of the document from a user given reference.

To use distance scoring on a query that has numerical fields, the user has to define

1. a reference and
2. a scale

for each field you want the function applied on. A reference is needed to define a distance for the document and a scale to define the rate of decay.

For each field in each found document, a decay function is be computed. The original score of the query is then multiplied with the individual function values computed for the fields. Distance scoring in this case behaves like a range query with smoothed box edges.

Distance scoring can be applied for an arbitrary number of numeric fields.

Example
----------------

Suppose you are searching for a hotel in a certain town. Your budget is limited. Also, you would like the hotel to be close to the town center, so the farther the hotel is from the desired location the less likely you are to check in.
You would like the query results that match your criterion (for example, "hotel, Nancy, non-smoker") to be scored with respect to distance to the town center and also the price.

Intuitively, you would like to define the town center as the origin and maybe you are willing to walk 2km to the town center from the hotel.
In this case your *reference* for the location field is the town center and the *scale* is ~2km.

If your budget is low, you would probably prefer something cheap above something expensive.
For the price field, the *reference* would be 0 Euros and the *scale* depends on how much you are willing to pay, for example 20 Euros.

Usage
----------------

In the above example, the fields might be called "price" for the price of the hotel and "location" for the coordinates of this hotel.

To apply distance scoring, embed any query in a distance_score query like this:

curl 'localhost:9200/hotels/_search/' -d '{
"query" : {
"distance_score" : {
"query" : {
"match": { "properties": "balcony" }
},
"gauss" : {
"location" : {
"reference": "11, 12",
"scale" : "2km"
},
"price" : {
"reference": "0",
"scale" : "20"
}
}
}
}
}'

The parameters (reference and scale) for the function (here is is "gauss") are given after the query for each field. Three different functions can be applied: Gauss ("gauss"), linear decay ("lin") and exponential decay ("exp").

Supported fields
----------------
Only single valued numeric fields, including time and geo locations, are be supported.

What is a field is missing?
----------------

Is the numeric field is missing in the document, that field will not be taken into account at all for this document. The function value for this field is set to 1 for this document.

Closes #3307