Files
tantivy/src/query/query_parser/logical_ast.rs
Paul Masurel 7d6cfa58e1 [WIP] Alternative take on boosted queries (#772)
* Alternative take on boosted queries

* Fixing unit test

* Added boosting to the query grammar.

* Made BoostQuery public.

* Added support for boosting field in QueryParser

Closes #547
2020-02-19 11:04:38 +09:00

87 lines
2.5 KiB
Rust

use crate::query::Occur;
use crate::schema::Field;
use crate::schema::Term;
use crate::schema::Type;
use std::fmt;
use std::ops::Bound;
#[derive(Clone)]
pub enum LogicalLiteral {
Term(Term),
Phrase(Vec<(usize, Term)>),
Range {
field: Field,
value_type: Type,
lower: Bound<Term>,
upper: Bound<Term>,
},
All,
}
pub enum LogicalAST {
Clause(Vec<(Occur, LogicalAST)>),
Leaf(Box<LogicalLiteral>),
Boost(Box<LogicalAST>, f32),
}
impl LogicalAST {
pub fn boost(self, boost: f32) -> LogicalAST {
if (boost - 1.0f32).abs() < std::f32::EPSILON {
self
} else {
LogicalAST::Boost(Box::new(self), boost)
}
}
}
fn occur_letter(occur: Occur) -> &'static str {
match occur {
Occur::Must => "+",
Occur::MustNot => "-",
Occur::Should => "",
}
}
impl fmt::Debug for LogicalAST {
fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> {
match *self {
LogicalAST::Clause(ref clause) => {
if clause.is_empty() {
write!(formatter, "<emptyclause>")?;
} else {
let (ref occur, ref subquery) = clause[0];
write!(formatter, "({}{:?}", occur_letter(*occur), subquery)?;
for &(ref occur, ref subquery) in &clause[1..] {
write!(formatter, " {}{:?}", occur_letter(*occur), subquery)?;
}
formatter.write_str(")")?;
}
Ok(())
}
LogicalAST::Boost(ref ast, boost) => write!(formatter, "{:?}^{}", ast, boost),
LogicalAST::Leaf(ref literal) => write!(formatter, "{:?}", literal),
}
}
}
impl From<LogicalLiteral> for LogicalAST {
fn from(literal: LogicalLiteral) -> LogicalAST {
LogicalAST::Leaf(Box::new(literal))
}
}
impl fmt::Debug for LogicalLiteral {
fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> {
match *self {
LogicalLiteral::Term(ref term) => write!(formatter, "{:?}", term),
LogicalLiteral::Phrase(ref terms) => write!(formatter, "\"{:?}\"", terms),
LogicalLiteral::Range {
ref lower,
ref upper,
..
} => write!(formatter, "({:?} TO {:?})", lower, upper),
LogicalLiteral::All => write!(formatter, "*"),
}
}
}