mirror of
https://github.com/meilisearch/MeiliSearch
synced 2024-11-29 16:24:26 +01:00
Implement the simplified NOT operator
This commit is contained in:
parent
01675771d5
commit
44744d9e67
@ -112,6 +112,7 @@ impl<'a> From<Span<'a>> for Token<'a> {
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||
pub enum FilterCondition<'a> {
|
||||
Not(Box<Self>),
|
||||
Condition { fid: Token<'a>, op: Condition<'a> },
|
||||
Or(Vec<Self>),
|
||||
And(Vec<Self>),
|
||||
@ -148,24 +149,6 @@ impl<'a> FilterCondition<'a> {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn negate(self) -> FilterCondition<'a> {
|
||||
use FilterCondition::*;
|
||||
|
||||
match self {
|
||||
Condition { fid, op } => match op.negate() {
|
||||
(op, None) => Condition { fid, op },
|
||||
(a, Some(b)) => Or(vec![
|
||||
Condition { fid: fid.clone(), op: a }.into(),
|
||||
Condition { fid, op: b }.into(),
|
||||
]),
|
||||
},
|
||||
Or(subfilters) => And(subfilters.into_iter().map(|x| x.negate().into()).collect()),
|
||||
And(subfilters) => Or(subfilters.into_iter().map(|x| x.negate().into()).collect()),
|
||||
GeoLowerThan { point, radius } => GeoGreaterThan { point, radius },
|
||||
GeoGreaterThan { point, radius } => GeoLowerThan { point, radius },
|
||||
}
|
||||
}
|
||||
|
||||
pub fn parse(input: &'a str) -> Result<Option<Self>, Error> {
|
||||
if input.trim().is_empty() {
|
||||
return Ok(None);
|
||||
@ -219,7 +202,9 @@ fn parse_and(input: Span) -> IResult<FilterCondition> {
|
||||
/// If we parse a `NOT` we MUST parse something behind.
|
||||
fn parse_not(input: Span) -> IResult<FilterCondition> {
|
||||
alt((
|
||||
map(preceded(ws(tuple((tag("NOT"), multispace1))), cut(parse_not)), |e| e.negate()),
|
||||
map(preceded(ws(tuple((tag("NOT"), multispace1))), cut(parse_not)), |e| {
|
||||
FilterCondition::Not(Box::new(e))
|
||||
}),
|
||||
parse_primary,
|
||||
))(input)
|
||||
}
|
||||
|
@ -360,6 +360,16 @@ impl<'a> Filter<'a> {
|
||||
filterable_fields: &HashSet<String>,
|
||||
) -> Result<RoaringBitmap> {
|
||||
match &self.condition {
|
||||
FilterCondition::Not(f) => {
|
||||
let all_ids = index.documents_ids(rtxn)?;
|
||||
let selected = Self::inner_evaluate(
|
||||
&(f.as_ref().clone()).into(),
|
||||
rtxn,
|
||||
index,
|
||||
filterable_fields,
|
||||
)?;
|
||||
return Ok(all_ids - selected);
|
||||
}
|
||||
FilterCondition::Condition { fid, op } => {
|
||||
if crate::is_faceted(fid.value(), filterable_fields) {
|
||||
let field_ids_map = index.fields_ids_map(rtxn)?;
|
||||
|
Loading…
Reference in New Issue
Block a user