The Util class provides common mathematical functions for custom scoring in Open Search. It includes three decay functions — gaussDecay, expDecay, and linearDecay — and three normalize overloads for mapping arbitrary values to the [0, 1] range.
Import the class with:
import com.aliyun.opensearch.cava.features.Util;Decay functions
Decay functions score documents based on how far a field value deviates from a reference point (origin). The further the value, the lower the score. Use them to implement distance-based or recency-based ranking — for example, ranking hotels by proximity while giving all hotels within 100 m the same top score.
How parameters interact
Four parameters control the decay curve:
| Parameter | Required | Description |
|---|---|---|
origin | Yes | The reference point. When value == origin, the score is 1.0. |
scale | Yes | The decay rate. Controls how quickly the score drops. At distance scale from origin, the score equals decay. |
decay | No | The score obtained when the value decreases from origin to scale. Defaults to 0.000001 when omitted. |
offset | No | The flat zone around origin. Any value within [origin - offset, origin + offset] scores 1.0. Defaults to 0 when omitted. |
Key relationship: a document at distance scale from origin receives a score of decay.
Choose a decay function
All three functions accept the same parameters and return values in [0, 1]. They differ in curve shape:
| Function | Curve shape | Characteristic |
|---|---|---|
gaussDecay | Bell curve (Gaussian) | Smooth, gradual falloff — most natural for real-world distances |
expDecay | Exponential | Score decreases exponentially with distance from the origin |
linearDecay | Straight line | Score decreases linearly with distance from the origin |
gaussDecay
Uses a Gaussian (bell curve) function to calculate the decay factor.
Signatures
static double gaussDecay(double origin, double value, double scale, double decay, double offset)
static double gaussDecay(double origin, double value, double scale, double decay) // offset = 0
static double gaussDecay(double origin, double value, double scale) // decay = 0.000001, offset = 0Return value: decay factor in [0, 1].
Example
This example scores search results by distance from a reference location. Hotels within 100 m of the origin (offset = 0.1 km) all score 1.0. At 5 km (scale), the score drops to near zero (decay = 0.000001).
package users.scorer;
import com.aliyun.opensearch.cava.framework.OpsScoreParams;
import com.aliyun.opensearch.cava.framework.OpsScorerInitParams;
import com.aliyun.opensearch.cava.framework.OpsRequest;
import com.aliyun.opensearch.cava.framework.OpsDoc;
import com.aliyun.opensearch.cava.features.Util;
import com.aliyun.opensearch.cava.features.Distance;
class BasicSimilarityScorer {
Distance _distance;
boolean init(OpsScorerInitParams params) {
_distance = Distance.create(params, "location", "query_location");
return true;
}
double score(OpsScoreParams params) {
double distanceValue = _distance.evaluate(params);
// origin=0, value=distanceValue, scale=5 km, decay=0.000001, offset=0.1 km
return Util.gaussDecay(0.0, distanceValue, 5.0, 0.000001, 0.1);
}
}Three-parameter variant (uses default decay = 0.000001, offset = 0):
double score(OpsScoreParams params) {
double distanceValue = _distance.evaluate(params);
return Util.gaussDecay(0.0, distanceValue, 5.0);
}expDecay
Uses an exponential function to calculate the decay factor. The application scenario is the same as gaussDecay.
Signatures
static double expDecay(double origin, double value, double scale, double decay, double offset)
static double expDecay(double origin, double value, double scale, double decay) // offset = 0
static double expDecay(double origin, double value, double scale) // decay = 0.000001, offset = 0Return value: decay factor in [0, 1].
Example
package users.scorer;
import com.aliyun.opensearch.cava.framework.OpsScoreParams;
import com.aliyun.opensearch.cava.framework.OpsScorerInitParams;
import com.aliyun.opensearch.cava.framework.OpsRequest;
import com.aliyun.opensearch.cava.framework.OpsDoc;
import com.aliyun.opensearch.cava.features.Util;
import com.aliyun.opensearch.cava.features.Distance;
class BasicSimilarityScorer {
Distance _distance;
boolean init(OpsScorerInitParams params) {
_distance = Distance.create(params, "location", "query_location");
return true;
}
double score(OpsScoreParams params) {
double distanceValue = _distance.evaluate(params);
return Util.expDecay(0.0, distanceValue, 5.0, 0.000001, 0.1);
}
}linearDecay
Uses a linear function to calculate the decay factor. The application scenario is the same as gaussDecay.
Signatures
static double linearDecay(double origin, double value, double scale, double decay, double offset)
static double linearDecay(double origin, double value, double scale, double decay) // offset = 0
static double linearDecay(double origin, double value, double scale) // decay = 0.000001, offset = 0Return value: decay factor in [0, 1].
Example
package users.scorer;
import com.aliyun.opensearch.cava.framework.OpsScoreParams;
import com.aliyun.opensearch.cava.framework.OpsScorerInitParams;
import com.aliyun.opensearch.cava.framework.OpsRequest;
import com.aliyun.opensearch.cava.framework.OpsDoc;
import com.aliyun.opensearch.cava.features.Util;
import com.aliyun.opensearch.cava.features.Distance;
class BasicSimilarityScorer {
Distance _distance;
boolean init(OpsScorerInitParams params) {
_distance = Distance.create(params, "location", "query_location");
return true;
}
double score(OpsScoreParams params) {
double distanceValue = _distance.evaluate(params);
return Util.linearDecay(0.0, distanceValue, 5.0, 0.000001, 0.1);
}
}Normalization functions
normalize maps a raw numeric value to the [0, 1] range. Three overloads are available, each using a different mathematical approach:
| Signature | Method | Formula | Returns 0 when |
|---|---|---|---|
normalize(value, max, min) | Linear | (value − min) / (max − min) | max < min |
normalize(value, max) | Logarithmic | log10(value) / log(max) | value < 1 and max < 1 |
normalize(value) | Arctangent | atan(value / 1000.0) × 2 / π (π = 3.141593) | — |
All three return a value in [0, 1].
normalize(double value, double max, double min)
Linear normalization. Maps value to [0, 1] relative to a known [min, max] range.
| Parameter | Description |
|---|---|
value | The value to normalize. |
max | The maximum expected value. |
min | The minimum expected value. |
Return value: Normalized result in [0, 1]. Returns 0 if max < min.
Example
This example normalizes a product price in the range [0, 100000]:
package users.scorer;
import com.aliyun.opensearch.cava.framework.OpsScoreParams;
import com.aliyun.opensearch.cava.framework.OpsScorerInitParams;
import com.aliyun.opensearch.cava.framework.OpsRequest;
import com.aliyun.opensearch.cava.framework.OpsDoc;
import com.aliyun.opensearch.cava.features.Util;
class BasicSimilarityScorer {
boolean init(OpsScorerInitParams params) {
return params.getDoc().requireAttribute("price");
}
double score(OpsScoreParams params) {
OpsDoc doc = params.getDoc();
long price = doc.docFieldLong("price");
return Util.normalize(price, 100000.0, 0.0);
}
}normalize(double value, double max)
Logarithmic normalization. Compresses large value ranges — useful when values span several orders of magnitude (e.g., view counts or download counts).
| Parameter | Description |
|---|---|
value | The value to normalize. |
max | The maximum expected value. |
Return value: Normalized result in [0, 1]. Returns 0 if both value and max are less than 1.
Example
package users.scorer;
import com.aliyun.opensearch.cava.framework.OpsScoreParams;
import com.aliyun.opensearch.cava.framework.OpsScorerInitParams;
import com.aliyun.opensearch.cava.framework.OpsRequest;
import com.aliyun.opensearch.cava.framework.OpsDoc;
import com.aliyun.opensearch.cava.features.Util;
class BasicSimilarityScorer {
boolean init(OpsScorerInitParams params) {
return params.getDoc().requireAttribute("price");
}
double score(OpsScoreParams params) {
OpsDoc doc = params.getDoc();
long price = doc.docFieldLong("price");
return Util.normalize(price, 100000.0);
}
}normalize(double value)
Arctangent normalization. Maps any non-negative value to [0, 1] without requiring a known maximum. The function scales slowly — values must be in the thousands to approach 1.0.
| Parameter | Description |
|---|---|
value | The value to normalize. |
Return value: Normalized result in [0, 1].
Example
package users.scorer;
import com.aliyun.opensearch.cava.framework.OpsScoreParams;
import com.aliyun.opensearch.cava.framework.OpsScorerInitParams;
import com.aliyun.opensearch.cava.framework.OpsRequest;
import com.aliyun.opensearch.cava.framework.OpsDoc;
import com.aliyun.opensearch.cava.features.Util;
class BasicSimilarityScorer {
boolean init(OpsScorerInitParams params) {
return params.getDoc().requireAttribute("price");
}
double score(OpsScoreParams params) {
OpsDoc doc = params.getDoc();
long price = doc.docFieldLong("price");
return Util.normalize(price);
}
}