Refine the FacetCondition from_array constructor

This commit is contained in:
Clément Renault 2021-05-03 12:51:33 +02:00 committed by Kerollmops
parent f7efde11d9
commit 79efded841
No known key found for this signature in database
GPG Key ID: 92ADA4E935E71FA4

View File

@ -1,9 +1,8 @@
use std::collections::{HashMap, HashSet}; use std::collections::HashSet;
use std::fmt::Debug; use std::fmt::Debug;
use std::ops::Bound::{self, Included, Excluded}; use std::ops::Bound::{self, Included, Excluded};
use std::str::FromStr; use std::str::FromStr;
use anyhow::Context;
use either::Either; use either::Either;
use heed::types::DecodeIgnore; use heed::types::DecodeIgnore;
use log::debug; use log::debug;
@ -12,7 +11,6 @@ use pest::iterators::{Pair, Pairs};
use pest::Parser; use pest::Parser;
use roaring::RoaringBitmap; use roaring::RoaringBitmap;
use crate::facet::FacetType;
use crate::heed_codec::facet::{FacetValueStringCodec, FacetLevelValueF64Codec}; use crate::heed_codec::facet::{FacetValueStringCodec, FacetLevelValueF64Codec};
use crate::{Index, FieldId, FieldsIdsMap, CboRoaringBitmapCodec}; use crate::{Index, FieldId, FieldsIdsMap, CboRoaringBitmapCodec};
@ -65,11 +63,9 @@ fn field_id<'a>(
{ {
// lexing ensures that we at least have a key // lexing ensures that we at least have a key
let key = items.next().unwrap(); let key = items.next().unwrap();
match fields_ids_map.id(key.as_str()) {
fields_ids_map Some(field_id) => Ok(field_id),
.id(key.as_str()) None => Err(PestError::new_from_span(
.ok_or_else(|| {
PestError::new_from_span(
ErrorVariant::CustomError { ErrorVariant::CustomError {
message: format!( message: format!(
"attribute `{}` not found, available attributes are: {}", "attribute `{}` not found, available attributes are: {}",
@ -78,8 +74,8 @@ fn field_id<'a>(
), ),
}, },
key.as_span(), key.as_span(),
) )),
}) }
} }
fn pest_parse<T>(pair: Pair<Rule>) -> (Result<T, pest::error::Error<Rule>>, String) fn pest_parse<T>(pair: Pair<Rule>) -> (Result<T, pest::error::Error<Rule>>, String)
@ -110,32 +106,6 @@ impl FacetCondition {
A: AsRef<str>, A: AsRef<str>,
B: AsRef<str>, B: AsRef<str>,
{ {
fn facet_condition(
fields_ids_map: &FieldsIdsMap,
faceted_fields: &HashMap<String, FacetType>,
key: &str,
value: &str,
) -> anyhow::Result<FacetCondition>
{
let fid = fields_ids_map.id(key).with_context(|| {
format!("{:?} isn't present in the fields ids map", key)
})?;
let ftype = faceted_fields.get(key).copied().with_context(|| {
format!("{:?} isn't a faceted field", key)
})?;
let (neg, value) = match value.trim().strip_prefix('-') {
Some(value) => (true, value.trim()),
None => (false, value.trim()),
};
let operator = match ftype {
FacetType::String => OperatorString(fid, FacetStringOperator::equal(value)),
FacetType::Number => OperatorNumber(fid, FacetNumberOperator::Equal(value.parse()?)),
};
if neg { Ok(operator.negate()) } else { Ok(operator) }
}
let fields_ids_map = index.fields_ids_map(rtxn)?; let fields_ids_map = index.fields_ids_map(rtxn)?;
let faceted_fields = index.faceted_fields(rtxn)?; let faceted_fields = index.faceted_fields(rtxn)?;
let mut ands = None; let mut ands = None;
@ -145,10 +115,7 @@ impl FacetCondition {
Either::Left(array) => { Either::Left(array) => {
let mut ors = None; let mut ors = None;
for rule in array { for rule in array {
let mut iter = rule.as_ref().splitn(2, ':'); let condition = FacetCondition::from_str(rtxn, index, rule.as_ref())?;
let key = iter.next().context("missing facet condition key")?;
let value = iter.next().context("missing facet condition value")?;
let condition = facet_condition(&fields_ids_map, &faceted_fields, key, value)?;
ors = match ors.take() { ors = match ors.take() {
Some(ors) => Some(Or(Box::new(ors), Box::new(condition))), Some(ors) => Some(Or(Box::new(ors), Box::new(condition))),
None => Some(condition), None => Some(condition),
@ -163,10 +130,7 @@ impl FacetCondition {
} }
}, },
Either::Right(rule) => { Either::Right(rule) => {
let mut iter = rule.as_ref().splitn(2, ':'); let condition = FacetCondition::from_str(rtxn, index, rule.as_ref())?;
let key = iter.next().context("missing facet condition key")?;
let value = iter.next().context("missing facet condition value")?;
let condition = facet_condition(&fields_ids_map, &faceted_fields, key, value)?;
ands = match ands.take() { ands = match ands.take() {
Some(ands) => Some(And(Box::new(ands), Box::new(condition))), Some(ands) => Some(And(Box::new(ands), Box::new(condition))),
None => Some(condition), None => Some(condition),