use std::borrow::Cow;
use serde::Serialize;
mod boost_mode;
mod decay_function;
mod field_value_factor;
mod random_score;
mod score_function;
mod score_mode;
mod script_score;
pub use boost_mode::*;
pub use decay_function::*;
pub use field_value_factor::*;
pub use random_score::*;
pub use score_function::*;
pub use score_mode::*;
pub use script_score::*;
use serde_json::{Map, Value};
use crate::util::is_empty_slice;
use crate::{QueryType, ToOpenSearchJson};
#[derive(Debug, Clone, Serialize, Default)]
pub struct FunctionScoreQuery<'a> {
#[serde(skip_serializing_if = "Option::is_none")]
pub query: Option<Box<QueryType<'a>>>,
#[serde(skip_serializing_if = "is_empty_slice", default, borrow)]
pub functions: Cow<'a, [ScoreFunction<'a>]>,
#[serde(skip_serializing_if = "Option::is_none")]
pub score_mode: Option<ScoreMode>,
#[serde(skip_serializing_if = "Option::is_none")]
pub boost_mode: Option<BoostMode>,
#[serde(skip_serializing_if = "Option::is_none")]
pub max_boost: Option<f64>,
#[serde(skip_serializing_if = "Option::is_none")]
pub boost: Option<f64>,
#[serde(skip_serializing_if = "Option::is_none")]
pub min_score: Option<f64>,
}
impl<'a> FunctionScoreQuery<'a> {
pub fn new() -> Self {
Self::default()
}
pub fn query(mut self, query: QueryType<'a>) -> Self {
self.query = Some(Box::new(query));
self
}
pub fn function(mut self, function: ScoreFunction<'a>) -> Self {
self.functions.to_mut().push(function);
self
}
pub fn score_mode(mut self, score_mode: ScoreMode) -> Self {
self.score_mode = Some(score_mode);
self
}
pub fn boost_mode(mut self, boost_mode: BoostMode) -> Self {
self.boost_mode = Some(boost_mode);
self
}
pub fn max_boost(mut self, max_boost: f64) -> Self {
self.max_boost = Some(max_boost);
self
}
pub fn boost(mut self, boost: f64) -> Self {
self.boost = Some(boost);
self
}
pub fn min_score(mut self, min_score: f64) -> Self {
self.min_score = Some(min_score);
self
}
}
impl<'a> From<FunctionScoreQuery<'a>> for QueryType<'a> {
fn from(function_score_query: FunctionScoreQuery<'a>) -> Self {
QueryType::FunctionScore(function_score_query)
}
}
impl<'a> ToOpenSearchJson for FunctionScoreQuery<'a> {
fn to_json(&self) -> Value {
let mut function_score_obj = Map::new();
if let Some(ref query) = self.query {
function_score_obj.insert("query".to_string(), query.to_json());
}
if !self.functions.is_empty() {
let functions: Vec<Value> = self.functions.iter().map(|f| f.to_json()).collect();
function_score_obj.insert("functions".to_string(), Value::Array(functions));
}
if let Some(ref score_mode) = self.score_mode {
function_score_obj.insert(
"score_mode".to_string(),
Value::String(match score_mode {
ScoreMode::Multiply => "multiply".to_string(),
ScoreMode::Sum => "sum".to_string(),
ScoreMode::Avg => "avg".to_string(),
ScoreMode::First => "first".to_string(),
ScoreMode::Max => "max".to_string(),
ScoreMode::Min => "min".to_string(),
}),
);
}
if let Some(ref boost_mode) = self.boost_mode {
function_score_obj.insert(
"boost_mode".to_string(),
Value::String(match boost_mode {
BoostMode::Multiply => "multiply".to_string(),
BoostMode::Replace => "replace".to_string(),
BoostMode::Sum => "sum".to_string(),
BoostMode::Avg => "avg".to_string(),
BoostMode::Max => "max".to_string(),
BoostMode::Min => "min".to_string(),
}),
);
}
if let Some(max_boost) = self.max_boost {
function_score_obj.insert("max_boost".to_string(), max_boost.into());
}
if let Some(boost) = self.boost {
function_score_obj.insert("boost".to_string(), boost.into());
}
if let Some(min_score) = self.min_score {
function_score_obj.insert("min_score".to_string(), min_score.into());
}
let mut result = Map::new();
result.insert(
"function_score".to_string(),
Value::Object(function_score_obj),
);
Value::Object(result)
}
}
#[derive(Default)]
pub struct FunctionScoreQueryBuilder<'a> {
pub query: Option<Box<QueryType<'a>>>,
pub functions: Cow<'a, [ScoreFunction<'a>]>,
pub score_mode: Option<ScoreMode>,
pub boost_mode: Option<BoostMode>,
pub max_boost: Option<f64>,
pub boost: Option<f64>,
pub min_score: Option<f64>,
}
impl<'a> FunctionScoreQueryBuilder<'a> {
pub fn new() -> Self {
Self::default()
}
pub fn query(&mut self, query: QueryType<'a>) -> &mut Self {
self.query = Some(Box::new(query));
self
}
pub fn function(&mut self, function: ScoreFunction<'a>) -> &mut Self {
self.functions.to_mut().push(function);
self
}
pub fn score_mode(&mut self, score_mode: ScoreMode) -> &mut Self {
self.score_mode = Some(score_mode);
self
}
pub fn boost_mode(&mut self, boost_mode: BoostMode) -> &mut Self {
self.boost_mode = Some(boost_mode);
self
}
pub fn max_boost(&mut self, max_boost: f64) -> &mut Self {
self.max_boost = Some(max_boost);
self
}
pub fn boost(&mut self, boost: f64) -> &mut Self {
self.boost = Some(boost);
self
}
pub fn min_score(&mut self, min_score: f64) -> &mut Self {
self.min_score = Some(min_score);
self
}
pub fn build(self) -> FunctionScoreQuery<'a> {
FunctionScoreQuery {
query: self.query,
functions: self.functions,
score_mode: self.score_mode,
boost_mode: self.boost_mode,
max_boost: self.max_boost,
boost: self.boost,
min_score: self.min_score,
}
}
}