pub enum Fusion {
Rrf {
k: u32,
},
Weighted {
weights: Vec<f32>,
},
}Expand description
How to combine several ranked SearchHit lists into one — the join point
for hybrid retrieval (e.g. a dense branch plus a sparse/lexical branch).
Choose by whether the branches’ scores are comparable. Rrf
looks only at ranks, so it is safe when the branches use different
similarity measures (cosine vs inner product) or wildly different scales;
Weighted sums raw scores and therefore assumes the
branches are already on a shared scale.
§Which to use for dense + sparse
A dense branch scores by cosine similarity (range roughly 0.0–1.0)
while a learned-lexical sparse branch scores by inner product (BGE-M3
sparse weights commonly sum to the tens or hundreds). Their scales do not
agree, so fusing them with Weighted directly lets the
sparse branch dominate regardless of the chosen weights. Prefer
Rrf when the branches disagree on scale — it is the
default for exactly this reason. If you need Weighted,
normalize each branch to a shared scale first (e.g. min-max to [0,1],
or softmax over the branch’s scores).
Scores are carried in SearchHit as f32. Inner-product scores are large
enough that the f64 → f32 narrowing in the backends can lose precision in
the low digits; this does not affect Rrf (rank-only) but is
a further reason to normalize before Weighted.
Variants§
Rrf
Reciprocal Rank Fusion: score(d) = Σ 1 / (k + rank_i(d)) over the
lists containing d, with 1-based ranks. Larger k flattens the
advantage of top ranks; 60 is the conventional default.
Fields
Weighted
Convex combination of raw scores, one weight per input list. A list that does not contain a hit contributes nothing for it.
All input lists must share a score scale. Do not fuse a cosine
branch with a raw inner-product branch without normalizing first — see
the type-level docs and Rrf for the scale-safe option.
Implementations§
Source§impl Fusion
impl Fusion
Sourcepub fn rrf() -> Self
pub fn rrf() -> Self
Reciprocal Rank Fusion with the conventional k = 60.
This is the recommended default for hybrid dense + sparse retrieval:
being rank-only, it is unaffected by the mismatched score scales of
cosine and inner product. See the Fusion type docs.
Sourcepub fn fuse(&self, hit_sets: &[Vec<SearchHit>]) -> Vec<SearchHit>
pub fn fuse(&self, hit_sets: &[Vec<SearchHit>]) -> Vec<SearchHit>
Fuse ranked lists into a single list, best first.
Every input list is expected to be sorted best-first already — RRF
derives its ranks from that order. The result uses the same ordering as
SearchHit itself: descending score, then ascending id.
§Panics
Weighted panics when the number of weights differs
from the number of lists, mirroring search::weighted_sum_fuse: a
mismatch means a branch would be silently dropped from the ranking.
Trait Implementations§
impl StructuralPartialEq for Fusion
Auto Trait Implementations§
impl Freeze for Fusion
impl RefUnwindSafe for Fusion
impl Send for Fusion
impl Sync for Fusion
impl Unpin for Fusion
impl UnsafeUnpin for Fusion
impl UnwindSafe for Fusion
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
impl<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> ErasedDestructor for Twhere
T: 'static,
Source§impl<T> Instrument for T
impl<T> Instrument for T
Source§fn instrument(self, span: Span) -> Instrumented<Self>
fn instrument(self, span: Span) -> Instrumented<Self>
Source§fn in_current_span(self) -> Instrumented<Self>
fn in_current_span(self) -> Instrumented<Self>
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self>
fn into_either(self, into_left: bool) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§impl<T> IntoRequest<T> for T
impl<T> IntoRequest<T> for T
Source§fn into_request(self) -> Request<T>
fn into_request(self) -> Request<T>
T in a tonic::RequestSource§impl<T> Pointable for T
impl<T> Pointable for T
Source§impl<T> PolicyExt for Twhere
T: ?Sized,
impl<T> PolicyExt for Twhere
T: ?Sized,
impl<T> Read<Exclusive, BecauseExclusive> for Twhere
T: ?Sized,
impl<T> Scalar for T
Source§impl<SS, SP> SupersetOf<SS> for SPwhere
SS: SubsetOf<SP>,
impl<SS, SP> SupersetOf<SS> for SPwhere
SS: SubsetOf<SP>,
Source§fn to_subset(&self) -> Option<SS>
fn to_subset(&self) -> Option<SS>
self from the equivalent element of its
superset. Read moreSource§fn is_in_subset(&self) -> bool
fn is_in_subset(&self) -> bool
self is actually part of its subset T (and can be converted to it).Source§fn to_subset_unchecked(&self) -> SS
fn to_subset_unchecked(&self) -> SS
self.to_subset but without any property checks. Always succeeds.Source§fn from_subset(element: &SS) -> SP
fn from_subset(element: &SS) -> SP
self to the equivalent element of its superset.