diff --git a/cli/src/main.rs b/cli/src/main.rs index b84ff3243..cae4d081f 100644 --- a/cli/src/main.rs +++ b/cli/src/main.rs @@ -262,7 +262,7 @@ impl Search { } if let Some(ref filter) = self.filter { - let condition = milli::FilterCondition::from_str(&txn, &index, filter)?; + let condition = milli::Filter::from_str(filter)?; search.filter(condition); } diff --git a/http-ui/src/main.rs b/http-ui/src/main.rs index d27c6d5bb..e3f8f0317 100644 --- a/http-ui/src/main.rs +++ b/http-ui/src/main.rs @@ -24,7 +24,8 @@ use milli::documents::DocumentBatchReader; use milli::update::UpdateIndexingStep::*; use milli::update::{IndexDocumentsMethod, Setting, UpdateBuilder}; use milli::{ - obkv_to_json, CompressionType, FilterCondition, Index, MatchingWords, SearchResult, SortError, + obkv_to_json, CompressionType, Filter as MilliFilter, FilterCondition, Index, MatchingWords, + SearchResult, SortError, }; use once_cell::sync::OnceCell; use rayon::ThreadPool; @@ -739,7 +740,7 @@ async fn main() -> anyhow::Result<()> { let filters = match query.filters { Some(condition) if !condition.trim().is_empty() => { - Some(FilterCondition::from_str(&rtxn, &index, &condition).unwrap()) + Some(MilliFilter::from_str(&condition).unwrap()) } _otherwise => None, }; @@ -747,7 +748,7 @@ async fn main() -> anyhow::Result<()> { let facet_filters = match query.facet_filters { Some(array) => { let eithers = array.into_iter().map(Into::into); - FilterCondition::from_array(&rtxn, &index, eithers).unwrap() + MilliFilter::from_array(eithers).unwrap() } _otherwise => None, }; diff --git a/milli/src/facet/mod.rs b/milli/src/facet/mod.rs index 274d2588d..aaa7a65ce 100644 --- a/milli/src/facet/mod.rs +++ b/milli/src/facet/mod.rs @@ -2,5 +2,7 @@ mod facet_type; mod facet_value; pub mod value_encoding; +pub use filter_parser::{Condition, FilterCondition, FilterParserError, Span, Token}; + pub use self::facet_type::FacetType; pub use self::facet_value::FacetValue; diff --git a/milli/src/lib.rs b/milli/src/lib.rs index 27453bf36..e2ecb060c 100644 --- a/milli/src/lib.rs +++ b/milli/src/lib.rs @@ -34,7 +34,9 @@ pub use self::heed_codec::{ RoaringBitmapLenCodec, StrBEU32Codec, StrStrU8Codec, }; pub use self::index::Index; -pub use self::search::{FacetDistribution, Filter, MatchingWords, Search, SearchResult}; +pub use self::search::{ + Condition, FacetDistribution, Filter, FilterCondition, MatchingWords, Search, SearchResult, +}; pub type Result = std::result::Result; diff --git a/milli/src/search/facet/filter_condition.rs b/milli/src/search/facet/filter_condition.rs index 2ba5a023e..29be3edf4 100644 --- a/milli/src/search/facet/filter_condition.rs +++ b/milli/src/search/facet/filter_condition.rs @@ -3,7 +3,7 @@ use std::ops::Bound::{self, Excluded, Included}; use std::str::FromStr; use either::Either; -use filter_parser::{Condition, FilterCondition, FilterParserError, Span, Token}; +pub use filter_parser::{Condition, FilterCondition, FilterParserError, Span, Token}; use heed::types::DecodeIgnore; use log::debug; use nom::error::{ErrorKind, VerboseError}; @@ -209,7 +209,7 @@ impl<'a> Filter<'a> { // 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 // field id and the level. - // TODO TAMO: return good error when we can't parse a span + let (left, right) = match operator { Condition::GreaterThan(val) => (Excluded(parse(val)?), Included(f64::MAX)), Condition::GreaterThanOrEqual(val) => (Included(parse(val)?), Included(f64::MAX)), @@ -315,10 +315,15 @@ impl<'a> Filter<'a> { match &self.condition { FilterCondition::Condition { fid, op } => { - // TODO: parse fid - let _ = fid; - let fid = 42; - Self::evaluate_operator(rtxn, index, numbers_db, strings_db, fid, &op) + let filterable_fields = index.fields_ids_map(rtxn)?; + if let Some(fid) = filterable_fields.id(fid.inner) { + Self::evaluate_operator(rtxn, index, numbers_db, strings_db, fid, &op) + } else { + // TODO TAMO: update the error message + return Err(UserError::InvalidFilter { + input: format!("Bad filter, available filters are {:?}", filterable_fields), + })?; + } } FilterCondition::Or(lhs, rhs) => { let lhs = Self::evaluate(&(lhs.as_ref().clone()).into(), rtxn, index)?; diff --git a/milli/src/search/facet/mod.rs b/milli/src/search/facet/mod.rs index d6f276fbb..c0b692de7 100644 --- a/milli/src/search/facet/mod.rs +++ b/milli/src/search/facet/mod.rs @@ -1,3 +1,5 @@ +pub use filter_parser::{Condition, FilterCondition}; + pub use self::facet_distribution::FacetDistribution; pub use self::facet_number::{FacetNumberIter, FacetNumberRange, FacetNumberRevRange}; pub use self::facet_string::FacetStringIter; diff --git a/milli/src/search/mod.rs b/milli/src/search/mod.rs index a31ead1ec..f52dd06f0 100644 --- a/milli/src/search/mod.rs +++ b/milli/src/search/mod.rs @@ -14,7 +14,7 @@ use meilisearch_tokenizer::{Analyzer, AnalyzerConfig}; use once_cell::sync::Lazy; use roaring::bitmap::RoaringBitmap; -pub use self::facet::{FacetDistribution, FacetNumberIter, Filter}; +pub use self::facet::{Condition, FacetDistribution, FacetNumberIter, Filter, FilterCondition}; pub use self::matching_words::MatchingWords; use self::query_tree::QueryTreeBuilder; use crate::error::UserError;