use crate::core::{Result, ScoreMode};
use crate::query::multi_term::ConstantScoreMultiTermSupplier;
use crate::query::{BoundQuery, Query, ScorerSupplier};
use crate::search::searcher::Searcher;
use crate::segment::reader::SegmentReader;
pub struct PrefixQuery {
pub field: String,
pub value: String,
}
impl Query for PrefixQuery {
fn bind(&self, _searcher: &Searcher, _score_mode: ScoreMode) -> Result<Box<dyn BoundQuery>> {
Ok(Box::new(BoundPrefixQuery {
field: self.field.clone(),
prefix: self.value.clone(),
}))
}
}
struct BoundPrefixQuery {
field: String,
prefix: String,
}
impl BoundQuery for BoundPrefixQuery {
fn scorer_supplier(&self, reader: &SegmentReader) -> Result<Option<Box<dyn ScorerSupplier>>> {
let field_id = match reader
.header()
.fields
.iter()
.find(|f| f.field_name == self.field)
.map(|f| f.field_id)
{
Some(id) => id,
None => return Ok(None),
};
let terms = reader.terms_with_prefix(field_id, &self.prefix);
if terms.is_empty() {
return Ok(None);
}
Ok(Some(Box::new(ConstantScoreMultiTermSupplier::new(
reader, field_id, terms,
))))
}
}