mirror of
https://github.com/meilisearch/MeiliSearch
synced 2024-11-30 00:34:26 +01:00
Fix the typo criterion
This commit is contained in:
parent
a273c46559
commit
c5a32fd4fa
@ -3,17 +3,13 @@ use std::{borrow::Cow, collections::HashMap, mem::take};
|
|||||||
use anyhow::bail;
|
use anyhow::bail;
|
||||||
use roaring::RoaringBitmap;
|
use roaring::RoaringBitmap;
|
||||||
|
|
||||||
use crate::search::query_tree::{Operation, Query, QueryKind};
|
use crate::search::query_tree::{maximum_typo, Operation, Query, QueryKind};
|
||||||
use crate::search::word_derivations;
|
use crate::search::word_derivations;
|
||||||
use super::{Candidates, Criterion, CriterionResult, Context, query_docids, query_pair_proximity_docids};
|
use super::{Candidates, Criterion, CriterionResult, Context, query_docids, query_pair_proximity_docids};
|
||||||
|
|
||||||
// FIXME we must stop when the number of typos is equal to
|
|
||||||
// the maximum number of typos for this query tree.
|
|
||||||
const MAX_NUM_TYPOS: u8 = 8;
|
|
||||||
|
|
||||||
pub struct Typo<'t> {
|
pub struct Typo<'t> {
|
||||||
ctx: &'t dyn Context,
|
ctx: &'t dyn Context,
|
||||||
query_tree: Option<Operation>,
|
query_tree: Option<(usize, Operation)>,
|
||||||
number_typos: u8,
|
number_typos: u8,
|
||||||
candidates: Candidates,
|
candidates: Candidates,
|
||||||
bucket_candidates: Option<RoaringBitmap>,
|
bucket_candidates: Option<RoaringBitmap>,
|
||||||
@ -31,7 +27,7 @@ impl<'t> Typo<'t> {
|
|||||||
{
|
{
|
||||||
Ok(Typo {
|
Ok(Typo {
|
||||||
ctx,
|
ctx,
|
||||||
query_tree,
|
query_tree: query_tree.map(|op| (maximum_typo(&op), op)),
|
||||||
number_typos: 0,
|
number_typos: 0,
|
||||||
candidates: candidates.map_or_else(Candidates::default, Candidates::Allowed),
|
candidates: candidates.map_or_else(Candidates::default, Candidates::Allowed),
|
||||||
bucket_candidates: None,
|
bucket_candidates: None,
|
||||||
@ -62,13 +58,17 @@ impl<'t> Typo<'t> {
|
|||||||
impl<'t> Criterion for Typo<'t> {
|
impl<'t> Criterion for Typo<'t> {
|
||||||
fn next(&mut self) -> anyhow::Result<Option<CriterionResult>> {
|
fn next(&mut self) -> anyhow::Result<Option<CriterionResult>> {
|
||||||
use Candidates::{Allowed, Forbidden};
|
use Candidates::{Allowed, Forbidden};
|
||||||
while self.number_typos < MAX_NUM_TYPOS {
|
loop {
|
||||||
match (&mut self.query_tree, &mut self.candidates) {
|
match (&mut self.query_tree, &mut self.candidates) {
|
||||||
(_, Allowed(candidates)) if candidates.is_empty() => {
|
(_, Allowed(candidates)) if candidates.is_empty() => {
|
||||||
self.query_tree = None;
|
self.query_tree = None;
|
||||||
self.candidates = Candidates::default();
|
self.candidates = Candidates::default();
|
||||||
},
|
},
|
||||||
(Some(query_tree), Allowed(candidates)) => {
|
(Some((max_typos, query_tree)), Allowed(candidates)) => {
|
||||||
|
if self.number_typos as usize > *max_typos {
|
||||||
|
self.query_tree = None;
|
||||||
|
self.candidates = Candidates::default();
|
||||||
|
} else {
|
||||||
let fst = self.ctx.words_fst();
|
let fst = self.ctx.words_fst();
|
||||||
let new_query_tree = if self.number_typos < 2 {
|
let new_query_tree = if self.number_typos < 2 {
|
||||||
alterate_query_tree(&fst, query_tree.clone(), self.number_typos, &mut self.typo_cache)?
|
alterate_query_tree(&fst, query_tree.clone(), self.number_typos, &mut self.typo_cache)?
|
||||||
@ -94,8 +94,13 @@ impl<'t> Criterion for Typo<'t> {
|
|||||||
candidates: new_candidates,
|
candidates: new_candidates,
|
||||||
bucket_candidates,
|
bucket_candidates,
|
||||||
}));
|
}));
|
||||||
|
}
|
||||||
},
|
},
|
||||||
(Some(query_tree), Forbidden(candidates)) => {
|
(Some((max_typos, query_tree)), Forbidden(candidates)) => {
|
||||||
|
if self.number_typos as usize > *max_typos {
|
||||||
|
self.query_tree = None;
|
||||||
|
self.candidates = Candidates::default();
|
||||||
|
} else {
|
||||||
let fst = self.ctx.words_fst();
|
let fst = self.ctx.words_fst();
|
||||||
let new_query_tree = if self.number_typos < 2 {
|
let new_query_tree = if self.number_typos < 2 {
|
||||||
alterate_query_tree(&fst, query_tree.clone(), self.number_typos, &mut self.typo_cache)?
|
alterate_query_tree(&fst, query_tree.clone(), self.number_typos, &mut self.typo_cache)?
|
||||||
@ -121,6 +126,7 @@ impl<'t> Criterion for Typo<'t> {
|
|||||||
candidates: new_candidates,
|
candidates: new_candidates,
|
||||||
bucket_candidates,
|
bucket_candidates,
|
||||||
}));
|
}));
|
||||||
|
}
|
||||||
},
|
},
|
||||||
(None, Allowed(_)) => {
|
(None, Allowed(_)) => {
|
||||||
let candidates = take(&mut self.candidates).into_inner();
|
let candidates = take(&mut self.candidates).into_inner();
|
||||||
@ -135,7 +141,8 @@ impl<'t> Criterion for Typo<'t> {
|
|||||||
Some(parent) => {
|
Some(parent) => {
|
||||||
match parent.next()? {
|
match parent.next()? {
|
||||||
Some(CriterionResult { query_tree, candidates, bucket_candidates }) => {
|
Some(CriterionResult { query_tree, candidates, bucket_candidates }) => {
|
||||||
self.query_tree = query_tree;
|
self.query_tree = query_tree.map(|op| (maximum_typo(&op), op));
|
||||||
|
self.number_typos = 0;
|
||||||
self.candidates = Candidates::Allowed(candidates);
|
self.candidates = Candidates::Allowed(candidates);
|
||||||
self.bucket_candidates = bucket_candidates;
|
self.bucket_candidates = bucket_candidates;
|
||||||
},
|
},
|
||||||
@ -147,8 +154,6 @@ impl<'t> Criterion for Typo<'t> {
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(None)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user