mirror of
https://github.com/meilisearch/MeiliSearch
synced 2025-07-04 20:37:15 +02:00
Use the Error enum everywhere in the project
This commit is contained in:
parent
ca78cb5aca
commit
312c2d1d8e
35 changed files with 385 additions and 300 deletions
|
@ -1,15 +1,15 @@
|
|||
use std::mem::take;
|
||||
|
||||
use anyhow::Context;
|
||||
use itertools::Itertools;
|
||||
use log::debug;
|
||||
use ordered_float::OrderedFloat;
|
||||
use roaring::RoaringBitmap;
|
||||
|
||||
use crate::error::FieldIdMapMissingEntry;
|
||||
use crate::search::criteria::{resolve_query_tree, CriteriaBuilder};
|
||||
use crate::search::facet::FacetIter;
|
||||
use crate::search::query_tree::Operation;
|
||||
use crate::{FieldId, Index};
|
||||
use crate::{FieldId, Index, Result};
|
||||
use super::{Criterion, CriterionParameters, CriterionResult};
|
||||
|
||||
/// Threshold on the number of candidates that will make
|
||||
|
@ -36,7 +36,7 @@ impl<'t> AscDesc<'t> {
|
|||
rtxn: &'t heed::RoTxn,
|
||||
parent: Box<dyn Criterion + 't>,
|
||||
field_name: String,
|
||||
) -> anyhow::Result<Self> {
|
||||
) -> Result<Self> {
|
||||
Self::new(index, rtxn, parent, field_name, true)
|
||||
}
|
||||
|
||||
|
@ -45,7 +45,7 @@ impl<'t> AscDesc<'t> {
|
|||
rtxn: &'t heed::RoTxn,
|
||||
parent: Box<dyn Criterion + 't>,
|
||||
field_name: String,
|
||||
) -> anyhow::Result<Self> {
|
||||
) -> Result<Self> {
|
||||
Self::new(index, rtxn, parent, field_name, false)
|
||||
}
|
||||
|
||||
|
@ -55,11 +55,14 @@ impl<'t> AscDesc<'t> {
|
|||
parent: Box<dyn Criterion + 't>,
|
||||
field_name: String,
|
||||
ascending: bool,
|
||||
) -> anyhow::Result<Self> {
|
||||
) -> Result<Self> {
|
||||
let fields_ids_map = index.fields_ids_map(rtxn)?;
|
||||
let field_id = fields_ids_map
|
||||
.id(&field_name)
|
||||
.with_context(|| format!("field {:?} isn't registered", field_name))?;
|
||||
.ok_or_else(|| FieldIdMapMissingEntry::FieldName {
|
||||
field_name: field_name.clone(),
|
||||
from_db_name: "asc-desc",
|
||||
})?;
|
||||
|
||||
Ok(AscDesc {
|
||||
index,
|
||||
|
@ -79,7 +82,7 @@ impl<'t> AscDesc<'t> {
|
|||
|
||||
impl<'t> Criterion for AscDesc<'t> {
|
||||
#[logging_timer::time("AscDesc::{}")]
|
||||
fn next(&mut self, params: &mut CriterionParameters) -> anyhow::Result<Option<CriterionResult>> {
|
||||
fn next(&mut self, params: &mut CriterionParameters) -> Result<Option<CriterionResult>> {
|
||||
// remove excluded candidates when next is called, instead of doing it in the loop.
|
||||
self.allowed_candidates -= params.excluded_candidates;
|
||||
|
||||
|
@ -162,7 +165,7 @@ fn facet_ordered<'t>(
|
|||
field_id: FieldId,
|
||||
ascending: bool,
|
||||
candidates: RoaringBitmap,
|
||||
) -> anyhow::Result<Box<dyn Iterator<Item = heed::Result<RoaringBitmap>> + 't>> {
|
||||
) -> Result<Box<dyn Iterator<Item = heed::Result<RoaringBitmap>> + 't>> {
|
||||
if candidates.len() <= CANDIDATES_THRESHOLD {
|
||||
let iter = iterative_facet_ordered_iter(index, rtxn, field_id, ascending, candidates)?;
|
||||
Ok(Box::new(iter.map(Ok)) as Box<dyn Iterator<Item = _>>)
|
||||
|
@ -186,7 +189,7 @@ fn iterative_facet_ordered_iter<'t>(
|
|||
field_id: FieldId,
|
||||
ascending: bool,
|
||||
candidates: RoaringBitmap,
|
||||
) -> anyhow::Result<impl Iterator<Item = RoaringBitmap> + 't> {
|
||||
) -> Result<impl Iterator<Item = RoaringBitmap> + 't> {
|
||||
let mut docids_values = Vec::with_capacity(candidates.len() as usize);
|
||||
for docid in candidates.iter() {
|
||||
let left = (field_id, docid, f64::MIN);
|
||||
|
|
|
@ -5,7 +5,7 @@ use std::mem::take;
|
|||
|
||||
use roaring::RoaringBitmap;
|
||||
|
||||
use crate::{TreeLevel, search::build_dfa};
|
||||
use crate::{TreeLevel, Result, search::build_dfa};
|
||||
use crate::search::criteria::Query;
|
||||
use crate::search::query_tree::{Operation, QueryKind};
|
||||
use crate::search::{word_derivations, WordDerivationsCache};
|
||||
|
@ -48,7 +48,7 @@ impl<'t> Attribute<'t> {
|
|||
|
||||
impl<'t> Criterion for Attribute<'t> {
|
||||
#[logging_timer::time("Attribute::{}")]
|
||||
fn next(&mut self, params: &mut CriterionParameters) -> anyhow::Result<Option<CriterionResult>> {
|
||||
fn next(&mut self, params: &mut CriterionParameters) -> Result<Option<CriterionResult>> {
|
||||
// remove excluded candidates when next is called, instead of doing it in the loop.
|
||||
if let Some((_, _, allowed_candidates)) = self.state.as_mut() {
|
||||
*allowed_candidates -= params.excluded_candidates;
|
||||
|
@ -224,7 +224,12 @@ struct QueryLevelIterator<'t, 'q> {
|
|||
}
|
||||
|
||||
impl<'t, 'q> QueryLevelIterator<'t, 'q> {
|
||||
fn new(ctx: &'t dyn Context<'t>, queries: &'q [Query], wdcache: &mut WordDerivationsCache) -> anyhow::Result<Option<Self>> {
|
||||
fn new(
|
||||
ctx: &'t dyn Context<'t>,
|
||||
queries: &'q [Query],
|
||||
wdcache: &mut WordDerivationsCache,
|
||||
) -> Result<Option<Self>>
|
||||
{
|
||||
let mut inner = Vec::with_capacity(queries.len());
|
||||
for query in queries {
|
||||
match &query.kind {
|
||||
|
@ -471,7 +476,7 @@ fn initialize_query_level_iterators<'t, 'q>(
|
|||
branches: &'q FlattenedQueryTree,
|
||||
allowed_candidates: &RoaringBitmap,
|
||||
wdcache: &mut WordDerivationsCache,
|
||||
) -> anyhow::Result<BinaryHeap<Branch<'t, 'q>>> {
|
||||
) -> Result<BinaryHeap<Branch<'t, 'q>>> {
|
||||
|
||||
let mut positions = BinaryHeap::with_capacity(branches.len());
|
||||
for branch in branches {
|
||||
|
@ -521,7 +526,7 @@ fn set_compute_candidates<'t>(
|
|||
branches: &FlattenedQueryTree,
|
||||
allowed_candidates: &RoaringBitmap,
|
||||
wdcache: &mut WordDerivationsCache,
|
||||
) -> anyhow::Result<Option<RoaringBitmap>>
|
||||
) -> Result<Option<RoaringBitmap>>
|
||||
{
|
||||
let mut branches_heap = initialize_query_level_iterators(ctx, branches, allowed_candidates, wdcache)?;
|
||||
let lowest_level = TreeLevel::min_value();
|
||||
|
@ -573,7 +578,7 @@ fn linear_compute_candidates(
|
|||
ctx: &dyn Context,
|
||||
branches: &FlattenedQueryTree,
|
||||
allowed_candidates: &RoaringBitmap,
|
||||
) -> anyhow::Result<BTreeMap<u64, RoaringBitmap>>
|
||||
) -> Result<BTreeMap<u64, RoaringBitmap>>
|
||||
{
|
||||
fn compute_candidate_rank(branches: &FlattenedQueryTree, words_positions: HashMap<String, RoaringBitmap>) -> u64 {
|
||||
let mut min_rank = u64::max_value();
|
||||
|
|
|
@ -14,7 +14,7 @@ use crate::search::criteria::{
|
|||
CriterionResult,
|
||||
resolve_query_tree,
|
||||
};
|
||||
use crate::TreeLevel;
|
||||
use crate::{TreeLevel, Result};
|
||||
|
||||
pub struct Exactness<'t> {
|
||||
ctx: &'t dyn Context<'t>,
|
||||
|
@ -45,7 +45,7 @@ impl<'t> Exactness<'t> {
|
|||
|
||||
impl<'t> Criterion for Exactness<'t> {
|
||||
#[logging_timer::time("Exactness::{}")]
|
||||
fn next(&mut self, params: &mut CriterionParameters) -> anyhow::Result<Option<CriterionResult>> {
|
||||
fn next(&mut self, params: &mut CriterionParameters) -> Result<Option<CriterionResult>> {
|
||||
// remove excluded candidates when next is called, instead of doing it in the loop.
|
||||
if let Some(state) = self.state.as_mut() {
|
||||
state.difference_with(params.excluded_candidates);
|
||||
|
@ -158,7 +158,7 @@ fn resolve_state(
|
|||
ctx: &dyn Context,
|
||||
state: State,
|
||||
query: &[ExactQueryPart],
|
||||
) -> anyhow::Result<(RoaringBitmap, Option<State>)>
|
||||
) -> Result<(RoaringBitmap, Option<State>)>
|
||||
{
|
||||
use State::*;
|
||||
match state {
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
use log::debug;
|
||||
use roaring::RoaringBitmap;
|
||||
|
||||
use crate::Result;
|
||||
use crate::search::query_tree::Operation;
|
||||
use crate::search::WordDerivationsCache;
|
||||
use super::{resolve_query_tree, Criterion, CriterionResult, CriterionParameters, Context};
|
||||
|
@ -29,7 +30,7 @@ impl<'t> Final<'t> {
|
|||
}
|
||||
|
||||
#[logging_timer::time("Final::{}")]
|
||||
pub fn next(&mut self, excluded_candidates: &RoaringBitmap) -> anyhow::Result<Option<FinalResult>> {
|
||||
pub fn next(&mut self, excluded_candidates: &RoaringBitmap) -> Result<Option<FinalResult>> {
|
||||
debug!("Final iteration");
|
||||
let excluded_candidates = &self.returned_candidates | excluded_candidates;
|
||||
let mut criterion_parameters = CriterionParameters {
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
use roaring::RoaringBitmap;
|
||||
|
||||
use crate::Result;
|
||||
use crate::search::query_tree::Operation;
|
||||
|
||||
use super::{Criterion, CriterionResult, CriterionParameters};
|
||||
|
||||
pub struct Initial {
|
||||
|
@ -22,7 +22,7 @@ impl Initial {
|
|||
|
||||
impl Criterion for Initial {
|
||||
#[logging_timer::time("Initial::{}")]
|
||||
fn next(&mut self, _: &mut CriterionParameters) -> anyhow::Result<Option<CriterionResult>> {
|
||||
fn next(&mut self, _: &mut CriterionParameters) -> Result<Option<CriterionResult>> {
|
||||
Ok(self.answer.take())
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,7 +4,7 @@ use std::borrow::Cow;
|
|||
use roaring::RoaringBitmap;
|
||||
|
||||
use crate::{FieldId, TreeLevel, search::{word_derivations, WordDerivationsCache}};
|
||||
use crate::{Index, DocumentId};
|
||||
use crate::{Index, DocumentId, Result};
|
||||
|
||||
use super::query_tree::{Operation, PrimitiveQueryPart, Query, QueryKind};
|
||||
use self::asc_desc::AscDesc;
|
||||
|
@ -26,7 +26,7 @@ mod words;
|
|||
pub mod r#final;
|
||||
|
||||
pub trait Criterion {
|
||||
fn next(&mut self, params: &mut CriterionParameters) -> anyhow::Result<Option<CriterionResult>>;
|
||||
fn next(&mut self, params: &mut CriterionParameters) -> Result<Option<CriterionResult>>;
|
||||
}
|
||||
|
||||
/// The result of a call to the parent criterion.
|
||||
|
@ -78,8 +78,9 @@ pub trait Context<'c> {
|
|||
fn synonyms(&self, word: &str) -> heed::Result<Option<Vec<Vec<String>>>>;
|
||||
fn searchable_fields_ids(&self) -> heed::Result<Vec<FieldId>>;
|
||||
fn field_id_word_count_docids(&self, field_id: FieldId, word_count: u8) -> heed::Result<Option<RoaringBitmap>>;
|
||||
fn word_level_position_docids(&self, word: &str, level: TreeLevel, left: u32, right: u32) -> Result<Option<RoaringBitmap>, heed::Error>;
|
||||
fn word_level_position_docids(&self, word: &str, level: TreeLevel, left: u32, right: u32) -> heed::Result<Option<RoaringBitmap>>;
|
||||
}
|
||||
|
||||
pub struct CriteriaBuilder<'t> {
|
||||
rtxn: &'t heed::RoTxn<'t>,
|
||||
index: &'t Index,
|
||||
|
@ -185,14 +186,14 @@ impl<'c> Context<'c> for CriteriaBuilder<'c> {
|
|||
self.index.field_id_word_count_docids.get(self.rtxn, &key)
|
||||
}
|
||||
|
||||
fn word_level_position_docids(&self, word: &str, level: TreeLevel, left: u32, right: u32) -> Result<Option<RoaringBitmap>, heed::Error> {
|
||||
fn word_level_position_docids(&self, word: &str, level: TreeLevel, left: u32, right: u32) -> heed::Result<Option<RoaringBitmap>> {
|
||||
let key = (word, level, left, right);
|
||||
self.index.word_level_position_docids.get(self.rtxn, &key)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'t> CriteriaBuilder<'t> {
|
||||
pub fn new(rtxn: &'t heed::RoTxn<'t>, index: &'t Index) -> anyhow::Result<Self> {
|
||||
pub fn new(rtxn: &'t heed::RoTxn<'t>, index: &'t Index) -> Result<Self> {
|
||||
let words_fst = index.words_fst(rtxn)?;
|
||||
let words_prefixes_fst = index.words_prefixes_fst(rtxn)?;
|
||||
Ok(Self { rtxn, index, words_fst, words_prefixes_fst })
|
||||
|
@ -203,7 +204,7 @@ impl<'t> CriteriaBuilder<'t> {
|
|||
query_tree: Option<Operation>,
|
||||
primitive_query: Option<Vec<PrimitiveQueryPart>>,
|
||||
filtered_candidates: Option<RoaringBitmap>,
|
||||
) -> anyhow::Result<Final<'t>>
|
||||
) -> Result<Final<'t>>
|
||||
{
|
||||
use crate::criterion::Criterion as Name;
|
||||
|
||||
|
@ -230,13 +231,13 @@ pub fn resolve_query_tree<'t>(
|
|||
ctx: &'t dyn Context,
|
||||
query_tree: &Operation,
|
||||
wdcache: &mut WordDerivationsCache,
|
||||
) -> anyhow::Result<RoaringBitmap>
|
||||
) -> Result<RoaringBitmap>
|
||||
{
|
||||
fn resolve_operation<'t>(
|
||||
ctx: &'t dyn Context,
|
||||
query_tree: &Operation,
|
||||
wdcache: &mut WordDerivationsCache,
|
||||
) -> anyhow::Result<RoaringBitmap>
|
||||
) -> Result<RoaringBitmap>
|
||||
{
|
||||
use Operation::{And, Phrase, Or, Query};
|
||||
|
||||
|
@ -244,7 +245,7 @@ pub fn resolve_query_tree<'t>(
|
|||
And(ops) => {
|
||||
let mut ops = ops.iter().map(|op| {
|
||||
resolve_operation(ctx, op, wdcache)
|
||||
}).collect::<anyhow::Result<Vec<_>>>()?;
|
||||
}).collect::<Result<Vec<_>>>()?;
|
||||
|
||||
ops.sort_unstable_by_key(|cds| cds.len());
|
||||
|
||||
|
@ -302,7 +303,7 @@ fn all_word_pair_proximity_docids<T: AsRef<str>, U: AsRef<str>>(
|
|||
left_words: &[(T, u8)],
|
||||
right_words: &[(U, u8)],
|
||||
proximity: u8
|
||||
) -> anyhow::Result<RoaringBitmap>
|
||||
) -> Result<RoaringBitmap>
|
||||
{
|
||||
let mut docids = RoaringBitmap::new();
|
||||
for (left, _l_typo) in left_words {
|
||||
|
@ -318,7 +319,7 @@ fn query_docids(
|
|||
ctx: &dyn Context,
|
||||
query: &Query,
|
||||
wdcache: &mut WordDerivationsCache,
|
||||
) -> anyhow::Result<RoaringBitmap>
|
||||
) -> Result<RoaringBitmap>
|
||||
{
|
||||
match &query.kind {
|
||||
QueryKind::Exact { word, .. } => {
|
||||
|
@ -354,7 +355,7 @@ fn query_pair_proximity_docids(
|
|||
right: &Query,
|
||||
proximity: u8,
|
||||
wdcache: &mut WordDerivationsCache,
|
||||
) -> anyhow::Result<RoaringBitmap>
|
||||
) -> Result<RoaringBitmap>
|
||||
{
|
||||
if proximity >= 8 {
|
||||
let mut candidates = query_docids(ctx, left, wdcache)?;
|
||||
|
@ -481,7 +482,7 @@ pub mod test {
|
|||
todo!()
|
||||
}
|
||||
|
||||
fn word_level_position_docids(&self, _word: &str, _level: TreeLevel, _left: u32, _right: u32) -> Result<Option<RoaringBitmap>, heed::Error> {
|
||||
fn word_level_position_docids(&self, _word: &str, _level: TreeLevel, _left: u32, _right: u32) -> heed::Result<Option<RoaringBitmap>> {
|
||||
todo!()
|
||||
}
|
||||
|
||||
|
|
|
@ -5,9 +5,10 @@ use std::mem::take;
|
|||
use roaring::RoaringBitmap;
|
||||
use log::debug;
|
||||
|
||||
use crate::{DocumentId, Position, search::{query_tree::QueryKind}};
|
||||
use crate::search::query_tree::{maximum_proximity, Operation, Query};
|
||||
use crate::search::{build_dfa, WordDerivationsCache};
|
||||
use crate::search::{query_tree::QueryKind};
|
||||
use crate::{DocumentId, Position, Result};
|
||||
use super::{
|
||||
Context,
|
||||
Criterion,
|
||||
|
@ -55,7 +56,7 @@ impl<'t> Proximity<'t> {
|
|||
|
||||
impl<'t> Criterion for Proximity<'t> {
|
||||
#[logging_timer::time("Proximity::{}")]
|
||||
fn next(&mut self, params: &mut CriterionParameters) -> anyhow::Result<Option<CriterionResult>> {
|
||||
fn next(&mut self, params: &mut CriterionParameters) -> Result<Option<CriterionResult>> {
|
||||
// remove excluded candidates when next is called, instead of doing it in the loop.
|
||||
if let Some((_, _, allowed_candidates)) = self.state.as_mut() {
|
||||
*allowed_candidates -= params.excluded_candidates;
|
||||
|
@ -161,7 +162,7 @@ fn resolve_candidates<'t>(
|
|||
proximity: u8,
|
||||
cache: &mut Cache,
|
||||
wdcache: &mut WordDerivationsCache,
|
||||
) -> anyhow::Result<RoaringBitmap>
|
||||
) -> Result<RoaringBitmap>
|
||||
{
|
||||
fn resolve_operation<'t>(
|
||||
ctx: &'t dyn Context,
|
||||
|
@ -169,7 +170,7 @@ fn resolve_candidates<'t>(
|
|||
proximity: u8,
|
||||
cache: &mut Cache,
|
||||
wdcache: &mut WordDerivationsCache,
|
||||
) -> anyhow::Result<Vec<(Query, Query, RoaringBitmap)>>
|
||||
) -> Result<Vec<(Query, Query, RoaringBitmap)>>
|
||||
{
|
||||
use Operation::{And, Phrase, Or};
|
||||
|
||||
|
@ -227,7 +228,7 @@ fn resolve_candidates<'t>(
|
|||
proximity: u8,
|
||||
cache: &mut Cache,
|
||||
wdcache: &mut WordDerivationsCache,
|
||||
) -> anyhow::Result<Vec<(Query, Query, RoaringBitmap)>>
|
||||
) -> Result<Vec<(Query, Query, RoaringBitmap)>>
|
||||
{
|
||||
fn pair_combinations(mana: u8, left_max: u8) -> impl Iterator<Item = (u8, u8)> {
|
||||
(0..=mana.min(left_max)).map(move |m| (m, mana - m))
|
||||
|
@ -281,7 +282,7 @@ fn resolve_candidates<'t>(
|
|||
proximity: u8,
|
||||
cache: &mut Cache,
|
||||
wdcache: &mut WordDerivationsCache,
|
||||
) -> anyhow::Result<Vec<(Query, Query, RoaringBitmap)>>
|
||||
) -> Result<Vec<(Query, Query, RoaringBitmap)>>
|
||||
{
|
||||
// Extract the first two elements but gives the tail
|
||||
// that is just after the first element.
|
||||
|
@ -324,13 +325,13 @@ fn resolve_plane_sweep_candidates(
|
|||
query_tree: &Operation,
|
||||
allowed_candidates: &RoaringBitmap,
|
||||
wdcache: &mut WordDerivationsCache,
|
||||
) -> anyhow::Result<BTreeMap<u8, RoaringBitmap>>
|
||||
) -> Result<BTreeMap<u8, RoaringBitmap>>
|
||||
{
|
||||
/// FIXME may be buggy with query like "new new york"
|
||||
fn plane_sweep(
|
||||
groups_positions: Vec<Vec<(Position, u8, Position)>>,
|
||||
consecutive: bool,
|
||||
) -> anyhow::Result<Vec<(Position, u8, Position)>>
|
||||
) -> Result<Vec<(Position, u8, Position)>>
|
||||
{
|
||||
fn compute_groups_proximity(
|
||||
groups: &[(usize, (Position, u8, Position))],
|
||||
|
@ -451,7 +452,7 @@ fn resolve_plane_sweep_candidates(
|
|||
rocache: &mut HashMap<&'a Operation, Vec<(Position, u8, Position)>>,
|
||||
words_positions: &HashMap<String, RoaringBitmap>,
|
||||
wdcache: &mut WordDerivationsCache,
|
||||
) -> anyhow::Result<Vec<(Position, u8, Position)>>
|
||||
) -> Result<Vec<(Position, u8, Position)>>
|
||||
{
|
||||
use Operation::{And, Phrase, Or};
|
||||
|
||||
|
|
|
@ -5,6 +5,7 @@ use roaring::RoaringBitmap;
|
|||
|
||||
use crate::search::query_tree::{maximum_typo, Operation, Query, QueryKind};
|
||||
use crate::search::{word_derivations, WordDerivationsCache};
|
||||
use crate::Result;
|
||||
use super::{
|
||||
Candidates,
|
||||
Context,
|
||||
|
@ -43,7 +44,7 @@ impl<'t> Typo<'t> {
|
|||
|
||||
impl<'t> Criterion for Typo<'t> {
|
||||
#[logging_timer::time("Typo::{}")]
|
||||
fn next(&mut self, params: &mut CriterionParameters) -> anyhow::Result<Option<CriterionResult>> {
|
||||
fn next(&mut self, params: &mut CriterionParameters) -> Result<Option<CriterionResult>> {
|
||||
use Candidates::{Allowed, Forbidden};
|
||||
// remove excluded candidates when next is called, instead of doing it in the loop.
|
||||
match self.state.as_mut() {
|
||||
|
@ -163,14 +164,14 @@ fn alterate_query_tree(
|
|||
mut query_tree: Operation,
|
||||
number_typos: u8,
|
||||
wdcache: &mut WordDerivationsCache,
|
||||
) -> anyhow::Result<Operation>
|
||||
) -> Result<Operation>
|
||||
{
|
||||
fn recurse(
|
||||
words_fst: &fst::Set<Cow<[u8]>>,
|
||||
operation: &mut Operation,
|
||||
number_typos: u8,
|
||||
wdcache: &mut WordDerivationsCache,
|
||||
) -> anyhow::Result<()>
|
||||
) -> Result<()>
|
||||
{
|
||||
use Operation::{And, Phrase, Or};
|
||||
|
||||
|
@ -218,7 +219,7 @@ fn resolve_candidates<'t>(
|
|||
number_typos: u8,
|
||||
cache: &mut HashMap<(Operation, u8), RoaringBitmap>,
|
||||
wdcache: &mut WordDerivationsCache,
|
||||
) -> anyhow::Result<RoaringBitmap>
|
||||
) -> Result<RoaringBitmap>
|
||||
{
|
||||
fn resolve_operation<'t>(
|
||||
ctx: &'t dyn Context,
|
||||
|
@ -226,7 +227,7 @@ fn resolve_candidates<'t>(
|
|||
number_typos: u8,
|
||||
cache: &mut HashMap<(Operation, u8), RoaringBitmap>,
|
||||
wdcache: &mut WordDerivationsCache,
|
||||
) -> anyhow::Result<RoaringBitmap>
|
||||
) -> Result<RoaringBitmap>
|
||||
{
|
||||
use Operation::{And, Phrase, Or, Query};
|
||||
|
||||
|
@ -277,7 +278,7 @@ fn resolve_candidates<'t>(
|
|||
mana: u8,
|
||||
cache: &mut HashMap<(Operation, u8), RoaringBitmap>,
|
||||
wdcache: &mut WordDerivationsCache,
|
||||
) -> anyhow::Result<RoaringBitmap>
|
||||
) -> Result<RoaringBitmap>
|
||||
{
|
||||
match branches.split_first() {
|
||||
Some((head, [])) => {
|
||||
|
|
|
@ -4,6 +4,7 @@ use log::debug;
|
|||
use roaring::RoaringBitmap;
|
||||
|
||||
use crate::search::query_tree::Operation;
|
||||
use crate::Result;
|
||||
use super::{Context, Criterion, CriterionParameters, CriterionResult, resolve_query_tree};
|
||||
|
||||
pub struct Words<'t> {
|
||||
|
@ -30,7 +31,7 @@ impl<'t> Words<'t> {
|
|||
|
||||
impl<'t> Criterion for Words<'t> {
|
||||
#[logging_timer::time("Words::{}")]
|
||||
fn next(&mut self, params: &mut CriterionParameters) -> anyhow::Result<Option<CriterionResult>> {
|
||||
fn next(&mut self, params: &mut CriterionParameters) -> Result<Option<CriterionResult>> {
|
||||
// remove excluded candidates when next is called, instead of doing it in the loop.
|
||||
if let Some(candidates) = self.candidates.as_mut() {
|
||||
*candidates -= params.excluded_candidates;
|
||||
|
|
|
@ -5,7 +5,7 @@ use roaring::RoaringBitmap;
|
|||
|
||||
use super::{Distinct, DocIter};
|
||||
use crate::heed_codec::facet::*;
|
||||
use crate::{DocumentId, FieldId, Index};
|
||||
use crate::{DocumentId, FieldId, Index, Result};
|
||||
|
||||
const FID_SIZE: usize = size_of::<FieldId>();
|
||||
const DOCID_SIZE: usize = size_of::<DocumentId>();
|
||||
|
@ -57,7 +57,7 @@ impl<'a> FacetDistinctIter<'a> {
|
|||
.get(self.txn, &(self.distinct, 0, key, key))
|
||||
}
|
||||
|
||||
fn distinct_string(&mut self, id: DocumentId) -> anyhow::Result<()> {
|
||||
fn distinct_string(&mut self, id: DocumentId) -> Result<()> {
|
||||
let iter = facet_string_values(id, self.distinct, self.index, self.txn)?;
|
||||
|
||||
for item in iter {
|
||||
|
@ -73,7 +73,7 @@ impl<'a> FacetDistinctIter<'a> {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
fn distinct_number(&mut self, id: DocumentId) -> anyhow::Result<()> {
|
||||
fn distinct_number(&mut self, id: DocumentId) -> Result<()> {
|
||||
let iter = facet_number_values(id, self.distinct, self.index, self.txn)?;
|
||||
|
||||
for item in iter {
|
||||
|
@ -92,7 +92,7 @@ impl<'a> FacetDistinctIter<'a> {
|
|||
/// Performs the next iteration of the facet distinct. This is a convenience method that is
|
||||
/// called by the Iterator::next implementation that transposes the result. It makes error
|
||||
/// handling easier.
|
||||
fn next_inner(&mut self) -> anyhow::Result<Option<DocumentId>> {
|
||||
fn next_inner(&mut self) -> Result<Option<DocumentId>> {
|
||||
// The first step is to remove all the excluded documents from our candidates
|
||||
self.candidates.difference_with(&self.excluded);
|
||||
|
||||
|
@ -129,7 +129,7 @@ fn facet_number_values<'a>(
|
|||
distinct: FieldId,
|
||||
index: &Index,
|
||||
txn: &'a heed::RoTxn,
|
||||
) -> anyhow::Result<heed::RoPrefix<'a, FieldDocIdFacetF64Codec, heed::types::Unit>> {
|
||||
) -> Result<heed::RoPrefix<'a, FieldDocIdFacetF64Codec, heed::types::Unit>> {
|
||||
let key = facet_values_prefix_key(distinct, id);
|
||||
|
||||
let iter = index
|
||||
|
@ -146,7 +146,7 @@ fn facet_string_values<'a>(
|
|||
distinct: FieldId,
|
||||
index: &Index,
|
||||
txn: &'a heed::RoTxn,
|
||||
) -> anyhow::Result<heed::RoPrefix<'a, FieldDocIdFacetStringCodec, heed::types::Unit>> {
|
||||
) -> Result<heed::RoPrefix<'a, FieldDocIdFacetStringCodec, heed::types::Unit>> {
|
||||
let key = facet_values_prefix_key(distinct, id);
|
||||
|
||||
let iter = index
|
||||
|
@ -159,7 +159,7 @@ fn facet_string_values<'a>(
|
|||
}
|
||||
|
||||
impl Iterator for FacetDistinctIter<'_> {
|
||||
type Item = anyhow::Result<DocumentId>;
|
||||
type Item = Result<DocumentId>;
|
||||
|
||||
fn next(&mut self) -> Option<Self::Item> {
|
||||
self.next_inner().transpose()
|
||||
|
|
|
@ -3,13 +3,13 @@ mod noop_distinct;
|
|||
|
||||
use roaring::RoaringBitmap;
|
||||
|
||||
use crate::DocumentId;
|
||||
use crate::{DocumentId, Result};
|
||||
pub use facet_distinct::FacetDistinct;
|
||||
pub use noop_distinct::NoopDistinct;
|
||||
|
||||
/// A trait implemented by document interators that are returned by calls to `Distinct::distinct`.
|
||||
/// It provides a way to get back the ownership to the excluded set.
|
||||
pub trait DocIter: Iterator<Item = anyhow::Result<DocumentId>> {
|
||||
pub trait DocIter: Iterator<Item = Result<DocumentId>> {
|
||||
/// Returns ownership on the internal exluded set.
|
||||
fn into_excluded(self) -> RoaringBitmap;
|
||||
}
|
||||
|
@ -106,7 +106,7 @@ mod test {
|
|||
|
||||
/// Checks that all the candidates are distinct, and returns the candidates number.
|
||||
pub(crate) fn validate_distinct_candidates(
|
||||
candidates: impl Iterator<Item=anyhow::Result<DocumentId>>,
|
||||
candidates: impl Iterator<Item = crate::Result<DocumentId>>,
|
||||
distinct: FieldId,
|
||||
index: &Index,
|
||||
) -> usize {
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
use roaring::{RoaringBitmap, bitmap::IntoIter};
|
||||
|
||||
use crate::DocumentId;
|
||||
use crate::{DocumentId, Result};
|
||||
use super::{DocIter, Distinct};
|
||||
|
||||
/// A distinct implementer that does not perform any distinct,
|
||||
|
@ -13,7 +13,7 @@ pub struct NoopDistinctIter {
|
|||
}
|
||||
|
||||
impl Iterator for NoopDistinctIter {
|
||||
type Item = anyhow::Result<DocumentId>;
|
||||
type Item = Result<DocumentId>;
|
||||
|
||||
fn next(&mut self) -> Option<Self::Item> {
|
||||
self.candidates.next().map(Ok)
|
||||
|
|
|
@ -2,15 +2,15 @@ use std::collections::{HashSet, BTreeMap};
|
|||
use std::ops::Bound::Unbounded;
|
||||
use std::{cmp, fmt};
|
||||
|
||||
use anyhow::Context;
|
||||
use heed::{Database, BytesDecode};
|
||||
use heed::types::{ByteSlice, Unit};
|
||||
use roaring::RoaringBitmap;
|
||||
|
||||
use crate::error::FieldIdMapMissingEntry;
|
||||
use crate::facet::FacetType;
|
||||
use crate::heed_codec::facet::FacetValueStringCodec;
|
||||
use crate::search::facet::{FacetIter, FacetRange};
|
||||
use crate::{Index, FieldId, DocumentId};
|
||||
use crate::{Index, FieldId, DocumentId, Result};
|
||||
|
||||
/// The default number of values by facets that will
|
||||
/// be fetched from the key-value store.
|
||||
|
@ -195,14 +195,15 @@ impl<'a> FacetDistribution<'a> {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn execute(&self) -> anyhow::Result<BTreeMap<String, BTreeMap<String, u64>>> {
|
||||
pub fn execute(&self) -> Result<BTreeMap<String, BTreeMap<String, u64>>> {
|
||||
let fields_ids_map = self.index.fields_ids_map(self.rtxn)?;
|
||||
let filterable_fields = self.index.filterable_fields(self.rtxn)?;
|
||||
|
||||
let mut distribution = BTreeMap::new();
|
||||
for name in filterable_fields {
|
||||
let fid = fields_ids_map.id(&name).with_context(|| {
|
||||
format!("missing field name {:?} from the fields id map", name)
|
||||
let fid = fields_ids_map.id(&name).ok_or_else(|| FieldIdMapMissingEntry::FieldName {
|
||||
field_name: name.clone(),
|
||||
from_db_name: "filterable-fields",
|
||||
})?;
|
||||
let values = self.facet_values(fid)?;
|
||||
distribution.insert(name, values);
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
use std::collections::HashSet;
|
||||
use std::fmt::Debug;
|
||||
use std::ops::Bound::{self, Included, Excluded};
|
||||
use std::result::Result as StdResult;
|
||||
use std::str::FromStr;
|
||||
|
||||
use either::Either;
|
||||
|
@ -11,8 +12,9 @@ use pest::iterators::{Pair, Pairs};
|
|||
use pest::Parser;
|
||||
use roaring::RoaringBitmap;
|
||||
|
||||
use crate::error::UserError;
|
||||
use crate::heed_codec::facet::{FacetValueStringCodec, FacetLevelValueF64Codec};
|
||||
use crate::{Index, FieldId, FieldsIdsMap, CboRoaringBitmapCodec};
|
||||
use crate::{Index, FieldId, FieldsIdsMap, CboRoaringBitmapCodec, Result};
|
||||
|
||||
use super::FacetRange;
|
||||
use super::parser::Rule;
|
||||
|
@ -60,7 +62,7 @@ impl FilterCondition {
|
|||
rtxn: &heed::RoTxn,
|
||||
index: &Index,
|
||||
array: I,
|
||||
) -> anyhow::Result<Option<FilterCondition>>
|
||||
) -> Result<Option<FilterCondition>>
|
||||
where I: IntoIterator<Item=Either<J, B>>,
|
||||
J: IntoIterator<Item=A>,
|
||||
A: AsRef<str>,
|
||||
|
@ -104,11 +106,11 @@ impl FilterCondition {
|
|||
rtxn: &heed::RoTxn,
|
||||
index: &Index,
|
||||
expression: &str,
|
||||
) -> anyhow::Result<FilterCondition>
|
||||
) -> Result<FilterCondition>
|
||||
{
|
||||
let fields_ids_map = index.fields_ids_map(rtxn)?;
|
||||
let filterable_fields = index.filterable_fields_ids(rtxn)?;
|
||||
let lexed = FilterParser::parse(Rule::prgm, expression)?;
|
||||
let lexed = FilterParser::parse(Rule::prgm, expression).map_err(UserError::FilterParsing)?;
|
||||
FilterCondition::from_pairs(&fields_ids_map, &filterable_fields, lexed)
|
||||
}
|
||||
|
||||
|
@ -116,7 +118,7 @@ impl FilterCondition {
|
|||
fim: &FieldsIdsMap,
|
||||
ff: &HashSet<FieldId>,
|
||||
expression: Pairs<Rule>,
|
||||
) -> anyhow::Result<Self>
|
||||
) -> Result<Self>
|
||||
{
|
||||
PREC_CLIMBER.climb(
|
||||
expression,
|
||||
|
@ -133,7 +135,7 @@ impl FilterCondition {
|
|||
Rule::term => Self::from_pairs(fim, ff, pair.into_inner()),
|
||||
_ => unreachable!(),
|
||||
},
|
||||
|lhs: anyhow::Result<Self>, op: Pair<Rule>, rhs: anyhow::Result<Self>| {
|
||||
|lhs: Result<Self>, op: Pair<Rule>, rhs: Result<Self>| {
|
||||
match op.as_rule() {
|
||||
Rule::or => Ok(Or(Box::new(lhs?), Box::new(rhs?))),
|
||||
Rule::and => Ok(And(Box::new(lhs?), Box::new(rhs?))),
|
||||
|
@ -158,16 +160,17 @@ impl FilterCondition {
|
|||
fields_ids_map: &FieldsIdsMap,
|
||||
filterable_fields: &HashSet<FieldId>,
|
||||
item: Pair<Rule>,
|
||||
) -> anyhow::Result<FilterCondition>
|
||||
) -> Result<FilterCondition>
|
||||
{
|
||||
let mut items = item.into_inner();
|
||||
let fid = field_id(fields_ids_map, filterable_fields, &mut items)?;
|
||||
let fid = field_id(fields_ids_map, filterable_fields, &mut items)
|
||||
.map_err(UserError::FilterParsing)?;
|
||||
|
||||
let (lresult, _) = pest_parse(items.next().unwrap());
|
||||
let (rresult, _) = pest_parse(items.next().unwrap());
|
||||
|
||||
let lvalue = lresult?;
|
||||
let rvalue = rresult?;
|
||||
let lvalue = lresult.map_err(UserError::FilterParsing)?;
|
||||
let rvalue = rresult.map_err(UserError::FilterParsing)?;
|
||||
|
||||
Ok(Operator(fid, Between(lvalue, rvalue)))
|
||||
}
|
||||
|
@ -176,10 +179,11 @@ impl FilterCondition {
|
|||
fields_ids_map: &FieldsIdsMap,
|
||||
filterable_fields: &HashSet<FieldId>,
|
||||
item: Pair<Rule>,
|
||||
) -> anyhow::Result<FilterCondition>
|
||||
) -> Result<FilterCondition>
|
||||
{
|
||||
let mut items = item.into_inner();
|
||||
let fid = field_id(fields_ids_map, filterable_fields, &mut items)?;
|
||||
let fid = field_id(fields_ids_map, filterable_fields, &mut items)
|
||||
.map_err(UserError::FilterParsing)?;
|
||||
|
||||
let value = items.next().unwrap();
|
||||
let (result, svalue) = pest_parse(value);
|
||||
|
@ -192,60 +196,68 @@ impl FilterCondition {
|
|||
fields_ids_map: &FieldsIdsMap,
|
||||
filterable_fields: &HashSet<FieldId>,
|
||||
item: Pair<Rule>,
|
||||
) -> anyhow::Result<FilterCondition>
|
||||
) -> Result<FilterCondition>
|
||||
{
|
||||
let mut items = item.into_inner();
|
||||
let fid = field_id(fields_ids_map, filterable_fields, &mut items)?;
|
||||
let fid = field_id(fields_ids_map, filterable_fields, &mut items)
|
||||
.map_err(UserError::FilterParsing)?;
|
||||
|
||||
let value = items.next().unwrap();
|
||||
let (result, _svalue) = pest_parse(value);
|
||||
let value = result.map_err(UserError::FilterParsing)?;
|
||||
|
||||
Ok(Operator(fid, GreaterThan(result?)))
|
||||
Ok(Operator(fid, GreaterThan(value)))
|
||||
}
|
||||
|
||||
fn greater_than_or_equal(
|
||||
fields_ids_map: &FieldsIdsMap,
|
||||
filterable_fields: &HashSet<FieldId>,
|
||||
item: Pair<Rule>,
|
||||
) -> anyhow::Result<FilterCondition>
|
||||
) -> Result<FilterCondition>
|
||||
{
|
||||
let mut items = item.into_inner();
|
||||
let fid = field_id(fields_ids_map, filterable_fields, &mut items)?;
|
||||
let fid = field_id(fields_ids_map, filterable_fields, &mut items)
|
||||
.map_err(UserError::FilterParsing)?;
|
||||
|
||||
let value = items.next().unwrap();
|
||||
let (result, _svalue) = pest_parse(value);
|
||||
let value = result.map_err(UserError::FilterParsing)?;
|
||||
|
||||
Ok(Operator(fid, GreaterThanOrEqual(result?)))
|
||||
Ok(Operator(fid, GreaterThanOrEqual(value)))
|
||||
}
|
||||
|
||||
fn lower_than(
|
||||
fields_ids_map: &FieldsIdsMap,
|
||||
filterable_fields: &HashSet<FieldId>,
|
||||
item: Pair<Rule>,
|
||||
) -> anyhow::Result<FilterCondition>
|
||||
) -> Result<FilterCondition>
|
||||
{
|
||||
let mut items = item.into_inner();
|
||||
let fid = field_id(fields_ids_map, filterable_fields, &mut items)?;
|
||||
let fid = field_id(fields_ids_map, filterable_fields, &mut items)
|
||||
.map_err(UserError::FilterParsing)?;
|
||||
|
||||
let value = items.next().unwrap();
|
||||
let (result, _svalue) = pest_parse(value);
|
||||
let value = result.map_err(UserError::FilterParsing)?;
|
||||
|
||||
Ok(Operator(fid, LowerThan(result?)))
|
||||
Ok(Operator(fid, LowerThan(value)))
|
||||
}
|
||||
|
||||
fn lower_than_or_equal(
|
||||
fields_ids_map: &FieldsIdsMap,
|
||||
filterable_fields: &HashSet<FieldId>,
|
||||
item: Pair<Rule>,
|
||||
) -> anyhow::Result<FilterCondition>
|
||||
) -> Result<FilterCondition>
|
||||
{
|
||||
let mut items = item.into_inner();
|
||||
let fid = field_id(fields_ids_map, filterable_fields, &mut items)?;
|
||||
let fid = field_id(fields_ids_map, filterable_fields, &mut items)
|
||||
.map_err(UserError::FilterParsing)?;
|
||||
|
||||
let value = items.next().unwrap();
|
||||
let (result, _svalue) = pest_parse(value);
|
||||
let value = result.map_err(UserError::FilterParsing)?;
|
||||
|
||||
Ok(Operator(fid, LowerThanOrEqual(result?)))
|
||||
Ok(Operator(fid, LowerThanOrEqual(value)))
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -260,7 +272,7 @@ impl FilterCondition {
|
|||
left: Bound<f64>,
|
||||
right: Bound<f64>,
|
||||
output: &mut RoaringBitmap,
|
||||
) -> anyhow::Result<()>
|
||||
) -> Result<()>
|
||||
{
|
||||
match (left, right) {
|
||||
// If the request is an exact value we must go directly to the deepest level.
|
||||
|
@ -332,7 +344,7 @@ impl FilterCondition {
|
|||
strings_db: heed::Database<FacetValueStringCodec, CboRoaringBitmapCodec>,
|
||||
field_id: FieldId,
|
||||
operator: &Operator,
|
||||
) -> anyhow::Result<RoaringBitmap>
|
||||
) -> Result<RoaringBitmap>
|
||||
{
|
||||
// Make sure we always bound the ranges with the field id and the level,
|
||||
// as the facets values are all in the same database and prefixed by the
|
||||
|
@ -390,7 +402,7 @@ impl FilterCondition {
|
|||
&self,
|
||||
rtxn: &heed::RoTxn,
|
||||
index: &Index,
|
||||
) -> anyhow::Result<RoaringBitmap>
|
||||
) -> Result<RoaringBitmap>
|
||||
{
|
||||
let numbers_db = index.facet_id_f64_docids;
|
||||
let strings_db = index.facet_id_string_docids;
|
||||
|
@ -422,7 +434,7 @@ fn field_id(
|
|||
fields_ids_map: &FieldsIdsMap,
|
||||
filterable_fields: &HashSet<FieldId>,
|
||||
items: &mut Pairs<Rule>,
|
||||
) -> Result<FieldId, PestError<Rule>>
|
||||
) -> StdResult<FieldId, PestError<Rule>>
|
||||
{
|
||||
// lexing ensures that we at least have a key
|
||||
let key = items.next().unwrap();
|
||||
|
@ -463,7 +475,7 @@ fn field_id(
|
|||
/// the original string that we tried to parse.
|
||||
///
|
||||
/// Returns the parsing error associated with the span if the conversion fails.
|
||||
fn pest_parse<T>(pair: Pair<Rule>) -> (Result<T, pest::error::Error<Rule>>, String)
|
||||
fn pest_parse<T>(pair: Pair<Rule>) -> (StdResult<T, pest::error::Error<Rule>>, String)
|
||||
where T: FromStr,
|
||||
T::Err: ToString,
|
||||
{
|
||||
|
|
|
@ -9,8 +9,9 @@ use crate::heed_codec::CboRoaringBitmapCodec;
|
|||
use crate::heed_codec::facet::FacetLevelValueF64Codec;
|
||||
use crate::{Index, FieldId};
|
||||
|
||||
pub use self::filter_condition::{FilterCondition, Operator};
|
||||
pub use self::facet_distribution::FacetDistribution;
|
||||
pub use self::filter_condition::{FilterCondition, Operator};
|
||||
pub(crate) use self::parser::Rule as ParserRule;
|
||||
|
||||
mod filter_condition;
|
||||
mod facet_distribution;
|
||||
|
|
|
@ -2,6 +2,7 @@ use std::borrow::Cow;
|
|||
use std::collections::hash_map::{Entry, HashMap};
|
||||
use std::fmt;
|
||||
use std::mem::take;
|
||||
use std::result::Result as StdResult;
|
||||
use std::str::Utf8Error;
|
||||
use std::time::Instant;
|
||||
|
||||
|
@ -14,10 +15,11 @@ use roaring::bitmap::RoaringBitmap;
|
|||
|
||||
use distinct::{Distinct, DocIter, FacetDistinct, NoopDistinct};
|
||||
use crate::search::criteria::r#final::{Final, FinalResult};
|
||||
use crate::{Index, DocumentId};
|
||||
use crate::{Index, DocumentId, Result};
|
||||
|
||||
pub use self::facet::{FilterCondition, FacetDistribution, FacetIter, Operator};
|
||||
pub use self::matching_words::MatchingWords;
|
||||
pub(crate) use self::facet::ParserRule;
|
||||
use self::query_tree::QueryTreeBuilder;
|
||||
|
||||
// Building these factories is not free.
|
||||
|
@ -93,7 +95,7 @@ impl<'a> Search<'a> {
|
|||
self
|
||||
}
|
||||
|
||||
pub fn execute(&self) -> anyhow::Result<SearchResult> {
|
||||
pub fn execute(&self) -> Result<SearchResult> {
|
||||
// We create the query tree by spliting the query into tokens.
|
||||
let before = Instant::now();
|
||||
let (query_tree, primitive_query) = match self.query.as_ref() {
|
||||
|
@ -152,7 +154,7 @@ impl<'a> Search<'a> {
|
|||
mut distinct: D,
|
||||
matching_words: MatchingWords,
|
||||
mut criteria: Final,
|
||||
) -> anyhow::Result<SearchResult>
|
||||
) -> Result<SearchResult>
|
||||
{
|
||||
let mut offset = self.offset;
|
||||
let mut initial_candidates = RoaringBitmap::new();
|
||||
|
@ -225,7 +227,7 @@ pub fn word_derivations<'c>(
|
|||
max_typo: u8,
|
||||
fst: &fst::Set<Cow<[u8]>>,
|
||||
cache: &'c mut WordDerivationsCache,
|
||||
) -> Result<&'c [(String, u8)], Utf8Error> {
|
||||
) -> StdResult<&'c [(String, u8)], Utf8Error> {
|
||||
match cache.entry((word.to_string(), is_prefix, max_typo)) {
|
||||
Entry::Occupied(entry) => Ok(entry.into_mut()),
|
||||
Entry::Vacant(entry) => {
|
||||
|
|
|
@ -7,7 +7,7 @@ use meilisearch_tokenizer::TokenKind;
|
|||
use roaring::RoaringBitmap;
|
||||
use slice_group_by::GroupBy;
|
||||
|
||||
use crate::Index;
|
||||
use crate::{Index, Result};
|
||||
|
||||
type IsOptionalWord = bool;
|
||||
type IsPrefix = bool;
|
||||
|
@ -219,7 +219,7 @@ impl<'a> QueryTreeBuilder<'a> {
|
|||
/// - if `authorize_typos` is set to `false` the query tree will be generated
|
||||
/// forcing all query words to match documents without any typo
|
||||
/// (the criterion `typo` will be ignored)
|
||||
pub fn build(&self, query: TokenStream) -> anyhow::Result<Option<(Operation, PrimitiveQuery)>> {
|
||||
pub fn build(&self, query: TokenStream) -> Result<Option<(Operation, PrimitiveQuery)>> {
|
||||
let stop_words = self.index.stop_words(self.rtxn)?;
|
||||
let primitive_query = create_primitive_query(query, stop_words, self.words_limit);
|
||||
if !primitive_query.is_empty() {
|
||||
|
@ -291,14 +291,14 @@ fn create_query_tree(
|
|||
optional_words: bool,
|
||||
authorize_typos: bool,
|
||||
query: &[PrimitiveQueryPart],
|
||||
) -> anyhow::Result<Operation>
|
||||
) -> Result<Operation>
|
||||
{
|
||||
/// Matches on the `PrimitiveQueryPart` and create an operation from it.
|
||||
fn resolve_primitive_part(
|
||||
ctx: &impl Context,
|
||||
authorize_typos: bool,
|
||||
part: PrimitiveQueryPart,
|
||||
) -> anyhow::Result<Operation>
|
||||
) -> Result<Operation>
|
||||
{
|
||||
match part {
|
||||
// 1. try to split word in 2
|
||||
|
@ -325,7 +325,7 @@ fn create_query_tree(
|
|||
ctx: &impl Context,
|
||||
authorize_typos: bool,
|
||||
query: &[PrimitiveQueryPart],
|
||||
) -> anyhow::Result<Operation>
|
||||
) -> Result<Operation>
|
||||
{
|
||||
const MAX_NGRAM: usize = 3;
|
||||
let mut op_children = Vec::new();
|
||||
|
@ -379,7 +379,7 @@ fn create_query_tree(
|
|||
ctx: &impl Context,
|
||||
authorize_typos: bool,
|
||||
query: PrimitiveQuery,
|
||||
) -> anyhow::Result<Operation>
|
||||
) -> Result<Operation>
|
||||
{
|
||||
let number_phrases = query.iter().filter(|p| p.is_phrase()).count();
|
||||
let mut operation_children = Vec::new();
|
||||
|
@ -532,7 +532,7 @@ mod test {
|
|||
authorize_typos: bool,
|
||||
words_limit: Option<usize>,
|
||||
query: TokenStream,
|
||||
) -> anyhow::Result<Option<(Operation, PrimitiveQuery)>>
|
||||
) -> Result<Option<(Operation, PrimitiveQuery)>>
|
||||
{
|
||||
let primitive_query = create_primitive_query(query, None, words_limit);
|
||||
if !primitive_query.is_empty() {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue