mirror of
https://github.com/meilisearch/MeiliSearch
synced 2025-07-04 04:17:10 +02:00
update some names and move some parser out of the lib.rs
This commit is contained in:
parent
7e5c5c4d27
commit
01dedde1c9
8 changed files with 318 additions and 285 deletions
|
@ -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
|
||||
|
|
|
@ -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'),
|
||||
))),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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>>,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue