1use crate::core::{Result, ScoreMode};
13
14use crate::query::multi_term::ConstantScoreMultiTermSupplier;
15use crate::query::{BoundQuery, Query, ScorerSupplier};
16use crate::search::searcher::Searcher;
17use crate::segment::reader::SegmentReader;
18
19pub struct PrefixQuery {
20 pub field: String,
21 pub value: String,
22}
23
24impl Query for PrefixQuery {
25 fn bind(&self, _searcher: &Searcher, _score_mode: ScoreMode) -> Result<Box<dyn BoundQuery>> {
26 Ok(Box::new(BoundPrefixQuery {
27 field: self.field.clone(),
28 prefix: self.value.clone(),
29 }))
30 }
31}
32
33struct BoundPrefixQuery {
34 field: String,
35 prefix: String,
36}
37
38impl BoundQuery for BoundPrefixQuery {
39 fn scorer_supplier(&self, reader: &SegmentReader) -> Result<Option<Box<dyn ScorerSupplier>>> {
40 let field_id = match reader
41 .header()
42 .fields
43 .iter()
44 .find(|f| f.field_name == self.field)
45 .map(|f| f.field_id)
46 {
47 Some(id) => id,
48 None => return Ok(None),
49 };
50
51 let terms = reader.terms_with_prefix(field_id, &self.prefix);
53 if terms.is_empty() {
54 return Ok(None);
55 }
56
57 Ok(Some(Box::new(ConstantScoreMultiTermSupplier::new(
58 reader, field_id, terms,
59 ))))
60 }
61}