Add support for ascending relevance ordering
- Id
- f12fbc57d4e7f5b32b148f7bb76734e17e46538c
- Author
- Caio
- Commit time
- 2020-01-10T16:47:57+01:00
Modified cantine/src/index.rs
-use std::{cmp::Ordering, convert::TryFrom};
+use std::{cmp::Ordering, convert::TryFrom, ops::Neg};
use bincode;
use serde::{Deserialize, Serialize};
use tique::top_collector::{
fastfield, CheckCondition, ConditionForSegment, ConditionalTopCollector,
- CustomScoreTopCollector, ScorerForSegment, SearchMarker,
+ CustomScoreTopCollector, ScorerForSegment, SearchMarker, TweakedScoreTopCollector,
};
#[derive(Clone)]
match sort {
Sort::Relevance => {
if ascending {
- todo!("TweakedScoreCollector");
- }
+ let condition = Paginator::new(self.id, after);
+ let top_collector =
+ TweakedScoreTopCollector::new(limit, condition, |_: &SegmentReader| {
+ |_doc, score: Score| score.neg()
+ });
- let condition = Paginator::new(self.id, after);
- let top_collector = ConditionalTopCollector::with_limit(limit, condition);
+ let result = searcher.search(query, &top_collector)?;
+ let items = self.addresses_to_ids(&searcher, &result.items)?;
- let result = searcher.search(query, &top_collector)?;
- let items = self.addresses_to_ids(&searcher, &result.items)?;
+ let num_items = items.len();
+ let cursor = if result.visited.saturating_sub(num_items) > 0 {
+ let last_score = result.items[num_items - 1].score;
+ let last_id = items[num_items - 1];
+ Some((last_score, last_id).into())
+ } else {
+ None
+ };
- let num_items = items.len();
- let cursor = if result.visited.saturating_sub(num_items) > 0 {
- let last_score = result.items[num_items - 1].score;
- let last_id = items[num_items - 1];
- Some((last_score, last_id).into())
+ Ok((result.total, items, cursor))
} else {
- None
- };
+ let condition = Paginator::new(self.id, after);
+ let top_collector = ConditionalTopCollector::with_limit(limit, condition);
- Ok((result.total, items, cursor))
+ let result = searcher.search(query, &top_collector)?;
+ let items = self.addresses_to_ids(&searcher, &result.items)?;
+
+ let num_items = items.len();
+ let cursor = if result.visited.saturating_sub(num_items) > 0 {
+ let last_score = result.items[num_items - 1].score;
+ let last_id = items[num_items - 1];
+ Some((last_score, last_id).into())
+ } else {
+ None
+ };
+
+ Ok((result.total, items, cursor))
+ }
}
Sort::NumIngredients => collect_unsigned!(num_ingredients),
Sort::InstructionsLength => collect_unsigned!(instructions_length),
Modified cantine/tests/index_integration.rs
model::{Recipe, RecipeId, Sort},
};
+use tique::queryparser::QueryParser;
+
struct GlobalData {
index: Index,
cantine: RecipeIndex,
assert!(cur_len >= last_len);
last_len = cur_len;
}
+
+ Ok(())
+}
+
+#[test]
+fn ascending_sort_works_for_relevance() -> Result<()> {
+ let reader = GLOBAL.index.reader()?;
+ let searcher = reader.searcher();
+
+ let parser = QueryParser::new(
+ GLOBAL.cantine.fulltext,
+ GLOBAL.index.tokenizer_for_field(GLOBAL.cantine.fulltext)?,
+ true,
+ );
+
+ let query = parser.parse("potato cheese")?.unwrap();
+
+ let (_total, found_ids, _next) = GLOBAL.cantine.search(
+ &searcher,
+ &query,
+ INDEX_SIZE,
+ Sort::Relevance,
+ false,
+ After::Start,
+ )?;
+
+ let (total, mut asc_found_ids, _next) = GLOBAL.cantine.search(
+ &searcher,
+ &query,
+ INDEX_SIZE,
+ Sort::Relevance,
+ true,
+ After::Start,
+ )?;
+
+ assert!(total > 5);
+ // NOTE Flaky test: the only reason the reverse check works
+ // here is because every matching doc has a distinct
+ // score.
+ // The reverse() logic doesn't work when scores are
+ // the same because the topk breaks even by id
+ asc_found_ids.reverse();
+ assert_eq!(found_ids, asc_found_ids);
Ok(())
}