flusso_query/handles/
compound.rs1use std::marker::PhantomData;
7
8use serde_json::{Map, Value};
9
10use super::{Common, common_opts, wrap};
11use crate::query::{AsQuery, Query, Root};
12
13fn clause_value<S>(query: impl AsQuery<S>) -> Value {
14 query
15 .into_query()
16 .map_or_else(super::match_all_value, |q| q.to_value())
17}
18
19pub fn constant_score<S>(filter: impl AsQuery<S>) -> ConstantScoreQuery<S> {
21 ConstantScoreQuery {
22 filter: clause_value(filter),
23 common: Common::default(),
24 _scope: PhantomData,
25 }
26}
27
28#[derive(Debug, Clone)]
30pub struct ConstantScoreQuery<S = Root> {
31 filter: Value,
32 common: Common,
33 _scope: PhantomData<fn() -> S>,
34}
35
36impl<S> ConstantScoreQuery<S> {
37 common_opts!(common);
38}
39
40impl<S> AsQuery<S> for ConstantScoreQuery<S> {
41 fn into_query(self) -> Option<Query<S>> {
42 let mut body = Map::new();
43 body.insert("filter".to_string(), self.filter);
44 self.common.write(&mut body);
45 Some(wrap("constant_score", body))
46 }
47}
48
49pub fn dis_max<S>(queries: impl IntoIterator<Item = impl AsQuery<S>>) -> DisMaxQuery<S> {
52 DisMaxQuery {
53 queries: queries.into_iter().map(clause_value).collect(),
54 tie_breaker: None,
55 common: Common::default(),
56 _scope: PhantomData,
57 }
58}
59
60#[derive(Debug, Clone)]
62pub struct DisMaxQuery<S = Root> {
63 queries: Vec<Value>,
64 tie_breaker: Option<f32>,
65 common: Common,
66 _scope: PhantomData<fn() -> S>,
67}
68
69impl<S> DisMaxQuery<S> {
70 #[must_use]
72 pub fn tie_breaker(mut self, tie_breaker: f32) -> Self {
73 self.tie_breaker = Some(tie_breaker);
74 self
75 }
76
77 common_opts!(common);
78}
79
80impl<S> AsQuery<S> for DisMaxQuery<S> {
81 fn into_query(self) -> Option<Query<S>> {
82 let mut body = Map::new();
83 body.insert("queries".to_string(), Value::Array(self.queries));
84 if let Some(tie_breaker) = self.tie_breaker {
85 body.insert("tie_breaker".to_string(), Value::from(tie_breaker));
86 }
87 self.common.write(&mut body);
88 Some(wrap("dis_max", body))
89 }
90}
91
92pub fn boosting<S>(
95 positive: impl AsQuery<S>,
96 negative: impl AsQuery<S>,
97 negative_boost: f32,
98) -> BoostingQuery<S> {
99 BoostingQuery {
100 positive: clause_value(positive),
101 negative: clause_value(negative),
102 negative_boost,
103 common: Common::default(),
104 _scope: PhantomData,
105 }
106}
107
108#[derive(Debug, Clone)]
110pub struct BoostingQuery<S = Root> {
111 positive: Value,
112 negative: Value,
113 negative_boost: f32,
114 common: Common,
115 _scope: PhantomData<fn() -> S>,
116}
117
118impl<S> BoostingQuery<S> {
119 common_opts!(common);
120}
121
122impl<S> AsQuery<S> for BoostingQuery<S> {
123 fn into_query(self) -> Option<Query<S>> {
124 let mut body = Map::new();
125 body.insert("positive".to_string(), self.positive);
126 body.insert("negative".to_string(), self.negative);
127 body.insert(
128 "negative_boost".to_string(),
129 Value::from(self.negative_boost),
130 );
131 self.common.write(&mut body);
132 Some(wrap("boosting", body))
133 }
134}
135
136pub fn function_score<S>(query: impl AsQuery<S>) -> FunctionScoreQuery<S> {
138 FunctionScoreQuery {
139 query: clause_value(query),
140 functions: Vec::new(),
141 opts: Map::new(),
142 common: Common::default(),
143 _scope: PhantomData,
144 }
145}
146
147#[derive(Debug, Clone)]
151pub struct FunctionScoreQuery<S = Root> {
152 query: Value,
153 functions: Vec<Value>,
154 opts: Map<String, Value>,
155 common: Common,
156 _scope: PhantomData<fn() -> S>,
157}
158
159impl<S> FunctionScoreQuery<S> {
160 #[must_use]
162 pub fn weight(mut self, weight: f32) -> Self {
163 let mut function = Map::new();
164 function.insert("weight".to_string(), Value::from(weight));
165 self.functions.push(Value::Object(function));
166 self
167 }
168
169 #[must_use]
171 pub fn weight_when(mut self, weight: f32, filter: impl AsQuery<S>) -> Self {
172 let mut function = Map::new();
173 function.insert("weight".to_string(), Value::from(weight));
174 function.insert("filter".to_string(), clause_value(filter));
175 self.functions.push(Value::Object(function));
176 self
177 }
178
179 #[must_use]
183 pub fn function(mut self, function: Value) -> Self {
184 self.functions.push(function);
185 self
186 }
187
188 #[must_use]
191 pub fn score_mode(mut self, score_mode: impl Into<String>) -> Self {
192 self.opts
193 .insert("score_mode".to_string(), Value::String(score_mode.into()));
194 self
195 }
196
197 #[must_use]
200 pub fn boost_mode(mut self, boost_mode: impl Into<String>) -> Self {
201 self.opts
202 .insert("boost_mode".to_string(), Value::String(boost_mode.into()));
203 self
204 }
205
206 #[must_use]
208 pub fn max_boost(mut self, max_boost: f32) -> Self {
209 self.opts
210 .insert("max_boost".to_string(), Value::from(max_boost));
211 self
212 }
213
214 #[must_use]
216 pub fn min_score(mut self, min_score: f32) -> Self {
217 self.opts
218 .insert("min_score".to_string(), Value::from(min_score));
219 self
220 }
221
222 common_opts!(common);
223}
224
225impl<S> AsQuery<S> for FunctionScoreQuery<S> {
226 fn into_query(self) -> Option<Query<S>> {
227 let mut body = self.opts;
228 body.insert("query".to_string(), self.query);
229 if !self.functions.is_empty() {
230 body.insert("functions".to_string(), Value::Array(self.functions));
231 }
232 self.common.write(&mut body);
233 Some(wrap("function_score", body))
234 }
235}