Boosting and scoring
LeanCorpus defaults to BM25 (Bm25Similarity).
Available similarities
| Similarity | Model | Notes |
|---|---|---|
Bm25Similarity |
BM25 (k1=1.2, b=0.75) | Default |
Bm25PlusSimilarity |
BM25+ with lower-bound delta | Avoids over-penalising long docs |
Bm25LSimilarity |
BM25L with tf/(1+tf) modulated delta | More nuanced lower-bound than BM25+ |
TfIdfSimilarity |
Classic TF-IDF | sqrt(tf) * idf / sqrt(dl) |
TfIdfAugmentedSimilarity |
Augmented TF-IDF | 0.5 + 0.5 * tf/max_tf |
TfIdfDoubleNormSimilarity |
Double-normalised TF-IDF | Two-stage normalisation |
TfIdfPivotedSimilarity |
Pivoted TF-IDF | Pivoted document length normalisation |
DirichletSimilarity |
LM with Dirichlet smoothing (μ=2000) | Bayesian smoothing towards collection |
LMAbsoluteDiscountingSimilarity |
LM with absolute discounting | Subtracts constant δ from counts |
LMJelinekMercerSimilarity |
LM with Jelinek-Mercer (λ=0.7) | Linear interpolation with collection |
All implement ISimilarity. Set on both writer (for norms) and searcher (for scoring):
var config = new IndexWriterConfig { Similarity = new Bm25PlusSimilarity() };
var searcherConfig = new IndexSearcherConfig { Similarity = new Bm25PlusSimilarity() };
Per-query boost
Every Query has a Boost (default 1.0). Multiplies that query's contribution within a BooleanQuery:
var q = new BooleanQuery.Builder()
.Add(new TermQuery("title", "fox") { Boost = 3.0f }, Occur.Should)
.Add(new TermQuery("body", "fox") { Boost = 1.0f }, Occur.Should)
.Build();
Constant scores
ConstantScoreQuery assigns a fixed score; skips BM25:
var filter = new ConstantScoreQuery(new TermQuery("status", "published"), score: 1.0f);
Function scores
FunctionScoreQuery blends BM25 with a numeric field:
| ScoreMode | Effect |
|---|---|
Multiply (default) |
score * fieldValue |
Replace |
fieldValue |
Sum |
score + fieldValue |
Max |
max(score, fieldValue) |
var boosted = new FunctionScoreQuery(
new TermQuery("body", "phone"), "popularity", ScoreMode.Multiply);
Index-time field boosting
Set per-field boost factors at write time. They persist in index norms and apply to every query:
var config = new IndexWriterConfig
{
FieldBoosts = new Dictionary<string, float>
{
["title"] = 3.0f,
["body"] = 1.0f,
},
};
A field boost of 2.0 makes every hit in that field count twice as much. Set to 0.0 to disable a field for ranking.