update some names and move some parser out of the lib.rs

This commit is contained in:
Tamo 2021-10-22 01:59:38 +02:00
parent 7e5c5c4d27
commit 01dedde1c9
No known key found for this signature in database
GPG key ID: 20CD8020AFA88D69
8 changed files with 318 additions and 285 deletions

View file

@ -16,20 +16,20 @@ use crate::heed_codec::facet::{
};
use crate::{distance_between_two_points, CboRoaringBitmapCodec, FieldId, Index, Result};
#[derive(Debug, Clone, PartialEq)]
pub enum FilterCondition {
Operator(FieldId, Operator),
#[derive(Debug, Clone)]
pub enum FilterCondition<'a> {
Operator(FieldId, Operator<'a>),
Or(Box<Self>, Box<Self>),
And(Box<Self>, Box<Self>),
Empty,
}
impl FilterCondition {
pub fn from_array<I, J, A, B>(
impl<'a> FilterCondition<'a> {
pub fn from_array<I, J, A: 'a, B: 'a>(
rtxn: &heed::RoTxn,
index: &Index,
array: I,
) -> Result<Option<FilterCondition>>
) -> Result<Option<FilterCondition<'a>>>
where
I: IntoIterator<Item = Either<J, B>>,
J: IntoIterator<Item = A>,
@ -73,8 +73,8 @@ impl FilterCondition {
pub fn from_str(
rtxn: &heed::RoTxn,
index: &Index,
expression: &str,
) -> Result<FilterCondition> {
expression: &'a str,
) -> Result<FilterCondition<'a>> {
let fields_ids_map = index.fields_ids_map(rtxn)?;
let filterable_fields = index.filterable_fields(rtxn)?;
let ctx =
@ -93,7 +93,7 @@ impl FilterCondition {
}
}
}
pub fn negate(self) -> FilterCondition {
pub fn negate(self) -> FilterCondition<'a> {
match self {
Operator(fid, op) => match op.negate() {
(op, None) => Operator(fid, op),
@ -106,7 +106,7 @@ impl FilterCondition {
}
}
impl FilterCondition {
impl<'a> FilterCondition<'a> {
/// Aggregates the documents ids that are part of the specified range automatically
/// going deeper through the levels.
fn explore_facet_number_levels(
@ -221,7 +221,7 @@ impl FilterCondition {
numbers_db: heed::Database<FacetLevelValueF64Codec, CboRoaringBitmapCodec>,
strings_db: heed::Database<FacetStringLevelZeroCodec, FacetStringLevelZeroValueCodec>,
field_id: FieldId,
operator: &Operator,
operator: &Operator<'a>,
) -> 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

View file

@ -28,25 +28,38 @@ use nom::multi::{many0, separated_list1};
use nom::number::complete::recognize_float;
use nom::sequence::{delimited, preceded, tuple};
use nom::IResult;
use nom_locate::LocatedSpan;
use self::Operator::*;
use super::FilterCondition;
use crate::{FieldId, FieldsIdsMap};
#[derive(Debug, Clone, PartialEq)]
pub enum Operator {
GreaterThan(f64),
GreaterThanOrEqual(f64),
Equal(Option<f64>, String),
NotEqual(Option<f64>, String),
LowerThan(f64),
LowerThanOrEqual(f64),
Between(f64, f64),
GeoLowerThan([f64; 2], f64),
GeoGreaterThan([f64; 2], f64),
pub enum FilterError {
AttributeNotFilterable(String),
}
impl Operator {
#[derive(Debug, Clone, PartialEq, Eq)]
struct Token<'a> {
pub position: Span<'a>,
pub inner: &'a str,
}
type Span<'a> = LocatedSpan<&'a str>;
#[derive(Debug, Clone)]
pub enum Operator<'a> {
GreaterThan(Token<'a>),
GreaterThanOrEqual(Token<'a>),
Equal(Option<Token<'a>>, Token<'a>),
NotEqual(Option<Token<'a>>, Token<'a>),
LowerThan(Token<'a>),
LowerThanOrEqual(Token<'a>),
Between(Token<'a>, Token<'a>),
GeoLowerThan([Token<'a>; 2], Token<'a>),
GeoGreaterThan([Token<'a>; 2], Token<'a>),
}
impl<'a> Operator<'a> {
/// This method can return two operations in case it must express
/// an OR operation for the between case (i.e. `TO`).
pub fn negate(self) -> (Self, Option<Self>) {
@ -180,16 +193,13 @@ impl<'a> ParseContext<'a> {
where
E: FilterParserError<'a>,
{
let error = match input.chars().nth(0) {
Some(ch) => Err(nom::Err::Failure(E::from_char(input, ch))),
None => Err(nom::Err::Failure(E::from_error_kind(input, ErrorKind::Eof))),
};
if !self.filterable_fields.contains(key) {
return error;
}
match self.fields_ids_map.id(key) {
Some(fid) => Ok(fid),
None => error,
Some(fid) if self.filterable_fields.contains(key) => Ok(fid),
_ => Err(nom::Err::Failure(E::add_context(
input,
"Attribute is not filterable",
E::from_char(input, 'T'),
))),
}
}

View file

@ -34,7 +34,8 @@ mod query_tree;
pub struct Search<'a> {
query: Option<String>,
filter: Option<FilterCondition>,
// this should be linked to the String in the query
filter: Option<FilterCondition<'a>>,
offset: usize,
limit: usize,
sort_criteria: Option<Vec<AscDesc>>,