Added a count method

This commit is contained in:
Paul Masurel
2018-02-17 15:02:51 +09:00
parent 292bb17346
commit 6676fe5717
6 changed files with 49 additions and 44 deletions

View File

@@ -1,15 +1,12 @@
mod boolean_query;
//mod boolean_scorer;
mod boolean_weight;
pub use self::boolean_query::BooleanQuery;
//pub use self::boolean_scorer::BooleanScorer;
#[cfg(test)]
mod tests {
use super::*;
use query::Scorer;
use query::Occur;
use query::Query;
use query::TermQuery;
@@ -19,10 +16,6 @@ mod tests {
use fastfield::U64FastFieldReader;
use schema::IndexRecordOption;
fn abs_diff(left: f32, right: f32) -> f32 {
(right - left).abs()
}
#[test]
pub fn test_boolean_query() {
let mut schema_builder = SchemaBuilder::default();
@@ -107,41 +100,4 @@ mod tests {
assert_eq!(matching_docs(&boolean_query), Vec::<u32>::new());
}
}
// #[test]
// pub fn test_boolean_scorer() {
// let occurs = vec![Occur::Should, Occur::Should];
// let occur_filter = OccurFilter::new(&occurs);
//
// let left_fieldnorms =
// U64FastFieldReader::from((0u64..9u64).map(|doc| doc * 3).collect::<Vec<u64>>());
//
// let left = VecPostings::from(vec![1, 2, 3]);
// let left_scorer = TermScorer {
// idf: 1f32,
// fieldnorm_reader_opt: Some(left_fieldnorms),
// postings: left,
// };
//
// let right_fieldnorms =
// U64FastFieldReader::from((0u64..9u64).map(|doc| doc * 5).collect::<Vec<u64>>());
// let right = VecPostings::from(vec![1, 3, 8]);
//
// let right_scorer = TermScorer {
// idf: 4f32,
// fieldnorm_reader_opt: Some(right_fieldnorms),
// postings: right,
// };
//
// let mut boolean_scorer = BooleanScorer::new(vec![left_scorer, right_scorer], occur_filter);
// assert_eq!(boolean_scorer.next(), Some(1u32));
// assert!(abs_diff(boolean_scorer.score(), 2.3662047) < 0.001);
// assert_eq!(boolean_scorer.next(), Some(2u32));
// assert!(abs_diff(boolean_scorer.score(), 0.20412415) < 0.001f32);
// assert_eq!(boolean_scorer.next(), Some(3u32));
// assert_eq!(boolean_scorer.next(), Some(8u32));
// assert!(abs_diff(boolean_scorer.score(), 0.31622776) < 0.001f32);
// assert!(!boolean_scorer.advance());
// }
}

View File

@@ -53,6 +53,16 @@ pub trait Query: fmt::Debug {
/// See [`Weight`](./trait.Weight.html).
fn weight(&self, searcher: &Searcher, scoring_enabled: bool) -> Result<Box<Weight>>;
fn count(&self, searcher: &Searcher) -> Result<usize> {
let weight = self.weight(searcher, false)?;
let mut result = 0;
for reader in searcher.segment_readers() {
result += weight.count(reader)? as usize;
}
Ok(result)
}
/// Search works as follows :
///
/// First the weight object associated to the query is created.

View File

@@ -1,12 +1,20 @@
use Score;
use query::Scorer;
/// The `ScoreCombiner` trait defines how to compute
/// an overall score given a list of scores.
pub trait ScoreCombiner: Default + Clone + Copy {
fn update<TScorer: Scorer>(&mut self, scorer: &mut TScorer);
fn clear(&mut self);
fn score(&self) -> Score;
}
/// Just ignores scores. The `DoNothingCombiner` does not
/// even call the scorers `.score()` function.
///
/// It is useful to optimize the case when scoring is disabled.
///
#[derive(Default, Clone, Copy)] //< these should not be too much work :)
pub struct DoNothingCombiner;
@@ -20,6 +28,8 @@ impl ScoreCombiner for DoNothingCombiner {
}
}
/// Sums the score of different scorers.
#[derive(Default, Clone, Copy)]
pub struct SumCombiner {
score: Score
@@ -40,6 +50,9 @@ impl ScoreCombiner for SumCombiner {
}
}
/// Sums the score of different scorers and keeps the count
/// of scorers which matched.
#[derive(Default, Clone, Copy)]
pub struct SumWithCoordsCombiner {
num_fields: usize,

View File

@@ -22,6 +22,14 @@ pub trait Scorer: DocSet {
collector.collect(self.doc(), self.score());
}
}
fn count(&mut self) -> u32 {
let mut count = 0u32;
while self.advance() {
count += 1u32;
}
count
}
}
impl<'a> Scorer for Box<Scorer + 'a> {
@@ -33,6 +41,11 @@ impl<'a> Scorer for Box<Scorer + 'a> {
let scorer = self.deref_mut();
scorer.collect(collector);
}
fn count(&mut self) -> u32 {
let scorer = self.deref_mut();
scorer.count()
}
}
/// `EmptyScorer` is a dummy `Scorer` in which no document matches.

View File

@@ -2,6 +2,7 @@ use Term;
use query::Weight;
use core::SegmentReader;
use query::Scorer;
use DocSet;
use postings::SegmentPostings;
use schema::IndexRecordOption;
use super::term_scorer::TermScorer;
@@ -19,6 +20,14 @@ impl Weight for TermWeight {
let specialized_scorer = self.specialized_scorer(reader)?;
Ok(box specialized_scorer)
}
fn count(&self, reader: &SegmentReader) -> Result<u32> {
if reader.num_deleted_docs() == 0 {
Ok(self.doc_freq)
} else {
Ok(self.specialized_scorer(reader)?.count())
}
}
}
impl TermWeight {

View File

@@ -10,4 +10,8 @@ pub trait Weight {
/// Returns the scorer for the given segment.
/// See [`Query`](./trait.Query.html).
fn scorer<'a>(&'a self, reader: &'a SegmentReader) -> Result<Box<Scorer + 'a>>;
fn count(&self, reader: &SegmentReader) -> Result<u32> {
Ok(self.scorer(reader)?.count())
}
}