FacetCondition can be created from array of facets

This commit is contained in:
Kerollmops 2021-01-07 10:17:27 +01:00
parent a8e3269ad6
commit cb5e57e2dd
No known key found for this signature in database
GPG Key ID: 92ADA4E935E71FA4

View File

@ -3,6 +3,7 @@ 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 either::Either;
use heed::types::{ByteSlice, DecodeIgnore}; use heed::types::{ByteSlice, DecodeIgnore};
use log::debug; use log::debug;
use num_traits::Bounded; use num_traits::Bounded;
@ -141,6 +142,81 @@ where T: FromStr,
} }
impl FacetCondition { impl FacetCondition {
pub fn from_array<I, J, A, B>(
rtxn: &heed::RoTxn,
index: &Index,
array: I,
) -> anyhow::Result<Option<FacetCondition>>
where I: IntoIterator<Item=Either<J, B>>,
J: IntoIterator<Item=A>,
A: AsRef<str>,
B: AsRef<str>,
{
fn facet_condition(
fields_ids_map: &FieldsIdsMap,
faceted_fields: &HashMap<FieldId, FacetType>,
key: &str,
value: &str,
) -> anyhow::Result<FacetCondition>
{
let fid = fields_ids_map.id(key).unwrap();
let ftype = faceted_fields.get(&fid).copied().unwrap();
let (neg, value) = match value.strip_prefix('-') {
Some(value) => (true, value),
None => (false, value),
};
let operator = match ftype {
FacetType::String => OperatorString(fid, FacetStringOperator::equal(value)),
FacetType::Float => OperatorF64(fid, FacetNumberOperator::Equal(value.parse()?)),
FacetType::Integer => OperatorI64(fid, FacetNumberOperator::Equal(value.parse()?)),
};
if neg { Ok(operator.negate()) } else { Ok(operator) }
}
let fields_ids_map = index.fields_ids_map(rtxn)?;
let faceted_fields = index.faceted_fields(rtxn)?;
let mut ands = None;
for either in array {
match either {
Either::Left(array) => {
let mut ors = None;
for rule in array {
let mut iter = rule.as_ref().splitn(2, ':');
let key = iter.next().unwrap();
let value = iter.next().unwrap();
let condition = facet_condition(&fields_ids_map, &faceted_fields, key, value)?;
ors = match ors.take() {
Some(ors) => Some(Or(Box::new(ors), Box::new(condition))),
None => Some(condition),
};
}
if let Some(rule) = ors {
ands = match ands.take() {
Some(ands) => Some(And(Box::new(ands), Box::new(rule))),
None => Some(rule),
};
}
},
Either::Right(rule) => {
let mut iter = rule.as_ref().splitn(2, ':');
let key = iter.next().unwrap();
let value = iter.next().unwrap();
let condition = facet_condition(&fields_ids_map, &faceted_fields, key, value)?;
ands = match ands.take() {
Some(ands) => Some(And(Box::new(ands), Box::new(condition))),
None => Some(condition),
};
}
}
}
Ok(ands)
}
pub fn from_str( pub fn from_str(
rtxn: &heed::RoTxn, rtxn: &heed::RoTxn,
index: &Index, index: &Index,