BM25F is based on BM25 to score a query term across multiple fields simultaneously. Assign different weights to each field, and BM25F merges the per-field BM25 scores into a single relevance score. The following figures show the BM25F scoring formulas.


Parameters
Allset*methods can be invoked only during the initialization of a score calculation object — inside theinit()method of your scorer class.
| Parameter | Method | Default | Effect |
|---|---|---|---|
| K | setParamK(double paramK) | 2.0 | Controls term-frequency saturation. Higher values allow a term's score to keep rising with more occurrences; lower values saturate sooner. Shown as in the formula. |
| B (per field) | setFieldParamB(CString fieldName, double paramB) | 0.1 | Controls how much field length affects scoring. 0 disables length normalization; 1 applies full normalization. |
| Total document count | setTotalDocNum(long totalDocNum) | 92000000 | The total number of documents in the application, used in the IDF calculation. |
| Average field length (per field) | setFieldAvgLength(CString fieldName, int avgFieldLength) | 20 | The expected average length for the field, used for length normalization. |
| Field weight (per field) | setFieldWeight(CString fieldName, double fieldWeight) | 1.0 | A multiplier applied to a field's BM25 score before merging. Higher values make the field contribute more to the final score. |
| Query group merge operation | setGroupScoreMergeOp(CString opName) | sum | How BM25 scores from multiple query groups are combined. Valid values: sum, max. Query groups are produced when an analyzer splits the original query. |
Methods
Factory functions
Use the factory functions to create a BM25F object.
`BM25F create(OpsScorerInitParams params, CString indexName)`
Creates a BM25F object that scores across all fields in the specified index.
params— initialization parameters. See OpsScorerInitParams.indexName— the index name. Must be a string constant.
`BM25F create(OpsScorerInitParams params, CString indexName, CString[] fields)`
Creates a BM25F object that scores across a specified subset of fields.
params— initialization parameters. See OpsScorerInitParams.indexName— the index name. Must be a string constant.fields— the fields to include in scoring.
Configuration methods
Call these methods inside init() to tune BM25F behavior. For per-field methods (setFieldParamB, setFieldAvgLength, setFieldWeight), if a list of fields is specified in the constructor, fieldName must be a string constant and must belong to the specified list.
| Method | Parameters |
|---|---|
void setGroupScoreMergeOp(CString opName) | opName — sum or max |
void setParamK(double paramK) | paramK — K value. Default: 2.0 |
void setFieldParamB(CString fieldName, double paramB) | fieldName — field name; paramB — B value. Default: 0.1 |
void setTotalDocNum(long totalDocNum) | totalDocNum — total document count. Default: 92000000 |
void setFieldAvgLength(CString fieldName, int avgFieldLength) | fieldName — field name; avgFieldLength — average length. Default: 20 |
void setFieldWeight(CString fieldName, double fieldWeight) | fieldName — field name; fieldWeight — weight multiplier. Default: 1.0 |
Score calculation
`double evaluate(OpsScoreParams params)`
Calculates the BM25F score of the query term across the configured fields.
params— score calculation parameters. See OpsScoreParams.Returns a
doublein the range[0, 1].
Example
The following example scores each query term across two fields — title and body — with different weights and tuning parameters for each field. All configuration happens inside init().
package users.scorer;
import com.aliyun.opensearch.cava.framework.OpsScoreParams;
import com.aliyun.opensearch.cava.framework.OpsScorerInitParams;
import com.aliyun.opensearch.cava.features.similarity.fieldmatch.BM25F;
class BasicSimilarityScorer {
BM25F _f1;
boolean init(OpsScorerInitParams params) {
CString[] fields1 = {"title", "body"};
// Create a BM25F object scoped to the "default" index and two fields
_f1 = BM25F.create(params, "default", fields1);
// Title: short field, high weight, stronger length normalization
_f1.setFieldAvgLength("title", 10);
_f1.setFieldWeight("title", 10D);
_f1.setFieldParamB("title", 0.6);
// Body: longer field, lower weight, moderate length normalization
_f1.setFieldAvgLength("body", 100);
_f1.setFieldWeight("body", 2D);
_f1.setFieldParamB("body", 0.5);
return true;
}
double score(OpsScoreParams params) {
return _f1.evaluate(params);
}
}
in the formula.