Decide the Occur at the raw parser level
- Id
- eae3998fd3c95cdcdc38c449c23eddacb334dc03
- Author
- Caio
- Commit time
- 2020-03-06T23:44:33+01:00
Modified tique/src/queryparser/interpreter.rs
-use super::raw::{parse_query, FieldNameValidator, Modifier, RawQuery};
+use super::raw::{parse_query, FieldNameValidator, RawQuery};
use tantivy::{
self,
let raw = &parsed[0];
let query = self.query_from_raw(&raw)?;
- if raw
- .modifier
- .as_ref()
- .map(|m| m == &Modifier::Prohibited)
- .unwrap_or(false)
- {
+ if raw.occur == Occur::MustNot {
Some(negate_query(query))
} else {
Some(query)
let mut num_must_not = 0;
for tok in parsed {
if let Some(query) = self.query_from_raw(&tok) {
- let occur = tok
- .modifier
- .as_ref()
- .map(|m| match m {
- Modifier::Mandatory => Occur::Must,
- Modifier::Prohibited => Occur::MustNot,
- })
- .unwrap_or(Occur::Should);
-
- if occur == Occur::MustNot {
+ if tok.occur == Occur::MustNot {
num_must_not += 1;
}
- subqueries.push((occur, query));
+ subqueries.push((tok.occur, query));
}
}
self.default_indices.clone()
};
- let mut queries = Vec::new();
- for idx in indices.into_iter() {
- // the indices are guaranteed to be valid
- if let Some((_name, opt_boost, interpreter)) = self.state.get(idx) {
- if let Some(mut query) = interpreter.to_query(raw_query) {
- if let Some(boost) = opt_boost {
- query = Box::new(BoostQuery::new(query, *boost));
+ let queries: Vec<Box<dyn Query>> = indices
+ .into_iter()
+ .flat_map(|i| self.state.get(i))
+ .flat_map(|(_, boost, interpreter)| {
+ interpreter.to_query(raw_query).map(|query| {
+ if let Some(val) = boost {
+ Box::new(BoostQuery::new(query, *val))
+ } else {
+ query
}
-
- queries.push(query);
- }
- }
- }
+ })
+ })
+ .collect();
match queries.len() {
0 => None,
- 1 => Some(queries.pop().unwrap()),
+ 1 => Some(queries.into_iter().nth(0).unwrap()),
_ => Some(Box::new(BooleanQuery::from(
queries
.into_iter()
Modified tique/src/queryparser/raw.rs
sequence::{delimited, preceded, separated_pair},
IResult,
};
+use tantivy::query::Occur;
#[derive(Debug, PartialEq)]
pub struct RawQuery<'a> {
pub input: &'a str,
pub is_phrase: bool,
pub field_name: Option<&'a str>,
- pub modifier: Option<Modifier>,
-}
-
-#[derive(Debug, PartialEq)]
-pub enum Modifier {
- Mandatory,
- Prohibited,
+ pub occur: Occur,
}
const FIELD_SEP: char = ':';
input,
is_phrase: false,
field_name: None,
- modifier: None,
+ occur: Occur::Should,
}
}
- pub fn prohibited(mut self) -> Self {
- debug_assert!(self.modifier.is_none());
- self.modifier.replace(Modifier::Prohibited);
+ pub fn must_not(mut self) -> Self {
+ debug_assert_eq!(Occur::Should, self.occur);
+ self.occur = Occur::MustNot;
self
}
- pub fn mandatory(mut self) -> Self {
- debug_assert!(self.modifier.is_none());
- self.modifier.replace(Modifier::Mandatory);
+ pub fn must(mut self) -> Self {
+ debug_assert_eq!(Occur::Should, self.occur);
+ self.occur = Occur::Must;
self
}
any_field_query,
)),
),
- |query| query.prohibited(),
+ |query| query.must_not(),
)(input)
}
any_field_query,
)),
),
- |query| query.mandatory(),
+ |query| query.must(),
)(input)
}
fn prohibited_term_extraction() {
assert_eq!(
parse_no_fields("-ads"),
- Ok(("", vec![RawQuery::new("ads").prohibited()]))
+ Ok(("", vec![RawQuery::new("ads").must_not()]))
)
}
fn mandatory_term_extraction() {
assert_eq!(
parse_no_fields("+love"),
- Ok(("", vec![RawQuery::new("love").mandatory()]))
+ Ok(("", vec![RawQuery::new("love").must()]))
)
}
parse_no_fields("-\"ads and tracking\""),
Ok((
"",
- vec![RawQuery::new("ads and tracking").prohibited().phrase()]
+ vec![RawQuery::new("ads and tracking").must_not().phrase()]
))
);
}
fn mandatory_phrase_extraction() {
assert_eq!(
parse_no_fields("+\"great food\""),
- Ok(("", vec![RawQuery::new("great food").mandatory().phrase()]))
+ Ok(("", vec![RawQuery::new("great food").must().phrase()]))
);
}
Ok((
"",
vec![
- RawQuery::new("peanut").mandatory(),
- RawQuery::new("peanut butter").phrase().prohibited(),
- RawQuery::new("sugar").prohibited(),
+ RawQuery::new("peanut").must(),
+ RawQuery::new("peanut butter").phrase().must_not(),
+ RawQuery::new("sugar").must_not(),
RawQuery::new("roast")
]
))
"",
vec![
RawQuery::new("-"),
- RawQuery::new("field:").prohibited(),
- RawQuery::new("\"\"").prohibited(),
+ RawQuery::new("field:").must_not(),
+ RawQuery::new("\"\"").must_not(),
RawQuery::new("\"\"").with_field("body"),
]
))
"",
vec![
RawQuery::new("potato:queen").with_field("title"),
- RawQuery::new("mash").with_field("instructions").mandatory(),
- RawQuery::new("how to fail").with_field("body").prohibited().phrase(),
+ RawQuery::new("mash").with_field("instructions").must(),
+ RawQuery::new("how to fail").with_field("body").must_not().phrase(),
RawQuery::new("golden peeler").with_field("ingredient").phrase()
]
))