lucisearch 0.8.0

Embeddable, in-process search engine — the SQLite/DuckDB of Elasticsearch
Documentation
//! Boost wrapper: multiplies inner query's score by a constant factor.
//!
//! Applied automatically by the parser when any query has a `boost` parameter.

use crate::core::{DocId, Result, ScoreMode, Scorer, TwoPhaseIterator};

use crate::query::{BoundQuery, Query, ScorerSupplier};
use crate::search::searcher::Searcher;
use crate::segment::reader::SegmentReader;

pub struct BoostQuery {
    pub(crate) inner: Box<dyn Query>,
    pub boost: f32,
}

impl Query for BoostQuery {
    fn bind(&self, searcher: &Searcher, score_mode: ScoreMode) -> Result<Box<dyn BoundQuery>> {
        let inner = self.inner.bind(searcher, score_mode)?;
        Ok(Box::new(BoundBoostQuery {
            inner,
            boost: self.boost,
        }))
    }
}

struct BoundBoostQuery {
    inner: Box<dyn BoundQuery>,
    boost: f32,
}

impl BoundQuery for BoundBoostQuery {
    fn scorer_supplier(&self, reader: &SegmentReader) -> Result<Option<Box<dyn ScorerSupplier>>> {
        let inner = match self.inner.scorer_supplier(reader)? {
            Some(s) => s,
            None => return Ok(None),
        };
        Ok(Some(Box::new(BoostScorerSupplier {
            inner,
            boost: self.boost,
        })))
    }
}

struct BoostScorerSupplier {
    inner: Box<dyn ScorerSupplier>,
    boost: f32,
}

impl ScorerSupplier for BoostScorerSupplier {
    fn cost(&self) -> u64 {
        self.inner.cost()
    }
    fn scorer(self: Box<Self>) -> Result<Box<dyn Scorer>> {
        let inner = self.inner.scorer()?;
        Ok(Box::new(BoostScorer {
            inner,
            boost: self.boost,
        }))
    }
}

struct BoostScorer {
    inner: Box<dyn Scorer>,
    boost: f32,
}

impl Scorer for BoostScorer {
    fn doc_id(&self) -> DocId {
        self.inner.doc_id()
    }
    fn next(&mut self) -> DocId {
        self.inner.next()
    }
    fn advance(&mut self, target: DocId) -> DocId {
        self.inner.advance(target)
    }
    fn score(&mut self) -> f32 {
        self.inner.score() * self.boost
    }
    fn two_phase(&mut self) -> Option<&mut dyn TwoPhaseIterator> {
        None
    }

    fn max_score(&self) -> f32 {
        self.inner.max_score() * self.boost
    }
    fn set_min_competitive_score(&mut self, min_score: f32) {
        if self.boost > 0.0 {
            self.inner.set_min_competitive_score(min_score / self.boost);
        }
    }
}