1use serde::{Serialize, Serializer};
20
21use crate::{json::ShouldSkip, units::OneOrMany};
22
23use super::{functions::Function, MinimumShouldMatch, Query, ScoreMode};
24
25#[derive(Debug, Copy, Clone)]
27pub enum BoostMode {
28 Multiply,
29 Replace,
30 Sum,
31 Avg,
32 Max,
33 Min,
34}
35
36impl Serialize for BoostMode {
37 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
38 where
39 S: Serializer,
40 {
41 match self {
42 BoostMode::Multiply => "multiply",
43 BoostMode::Replace => "replace",
44 BoostMode::Sum => "sum",
45 BoostMode::Avg => "avg",
46 BoostMode::Max => "max",
47 BoostMode::Min => "min",
48 }
49 .serialize(serializer)
50 }
51}
52
53#[derive(Debug, Default, Serialize)]
55pub struct ConstantScoreQuery {
56 query: Query,
57 #[serde(skip_serializing_if = "ShouldSkip::should_skip")]
58 boost: Option<f64>,
59}
60
61impl Query {
62 pub fn build_constant_score<A>(query: A) -> ConstantScoreQuery
63 where
64 A: Into<Query>,
65 {
66 ConstantScoreQuery {
67 query: query.into(),
68 ..Default::default()
69 }
70 }
71}
72
73impl ConstantScoreQuery {
74 add_field!(with_boost, boost, f64);
75
76 build!(ConstantScore);
77}
78
79#[derive(Debug, Default, Serialize)]
81pub struct BoolQuery {
82 #[serde(skip_serializing_if = "ShouldSkip::should_skip")]
83 must: Option<OneOrMany<Query>>,
84 #[serde(skip_serializing_if = "ShouldSkip::should_skip")]
85 filter: Option<Query>,
86 #[serde(skip_serializing_if = "ShouldSkip::should_skip")]
87 should: Option<OneOrMany<Query>>,
88 #[serde(skip_serializing_if = "ShouldSkip::should_skip")]
89 must_not: Option<OneOrMany<Query>>,
90 #[serde(skip_serializing_if = "ShouldSkip::should_skip")]
91 minimum_should_match: Option<MinimumShouldMatch>,
92 #[serde(skip_serializing_if = "ShouldSkip::should_skip")]
93 boost: Option<f64>,
94 #[serde(skip_serializing_if = "ShouldSkip::should_skip")]
95 disable_coord: Option<bool>,
96}
97
98impl Query {
99 pub fn build_bool() -> BoolQuery {
100 Default::default()
101 }
102}
103
104impl BoolQuery {
105 add_field!(with_must, must, OneOrMany<Query>);
106 add_field!(with_filter, filter, Query);
107 add_field!(with_should, should, OneOrMany<Query>);
108 add_field!(with_must_not, must_not, OneOrMany<Query>);
109 add_field!(
110 with_minimum_should_match,
111 minimum_should_match,
112 MinimumShouldMatch
113 );
114 add_field!(with_boost, boost, f64);
115 add_field!(with_disable_coord, disable_coord, bool);
116
117 build!(Bool);
118}
119
120#[derive(Debug, Default, Serialize)]
122pub struct DisMaxQuery {
123 #[serde(skip_serializing_if = "ShouldSkip::should_skip")]
124 tie_breaker: Option<f64>,
125 #[serde(skip_serializing_if = "ShouldSkip::should_skip")]
126 boost: Option<f64>,
127 queries: Vec<Query>,
128}
129
130impl Query {
131 pub fn build_dis_max<A>(queries: A) -> DisMaxQuery
132 where
133 A: Into<Vec<Query>>,
134 {
135 DisMaxQuery {
136 queries: queries.into(),
137 ..Default::default()
138 }
139 }
140}
141
142impl DisMaxQuery {
143 add_field!(with_tie_breaker, tie_breaker, f64);
144 add_field!(with_boost, boost, f64);
145
146 build!(DisMax);
147}
148
149#[derive(Debug, Default, Serialize)]
151pub struct FunctionScoreQuery {
152 #[serde(skip_serializing_if = "ShouldSkip::should_skip")]
153 query: Option<Query>,
154 #[serde(skip_serializing_if = "ShouldSkip::should_skip")]
155 boost: Option<f64>,
156 functions: Vec<Function>,
157 #[serde(skip_serializing_if = "ShouldSkip::should_skip")]
158 max_boost: Option<f64>,
159 #[serde(skip_serializing_if = "ShouldSkip::should_skip")]
160 score_mode: Option<ScoreMode>,
161 #[serde(skip_serializing_if = "ShouldSkip::should_skip")]
162 boost_mode: Option<BoostMode>,
163 #[serde(skip_serializing_if = "ShouldSkip::should_skip")]
164 min_score: Option<f64>,
165}
166
167impl Query {
168 pub fn build_function_score() -> FunctionScoreQuery {
169 Default::default()
170 }
171}
172
173impl FunctionScoreQuery {
174 add_field!(with_query, query, Query);
175 add_field!(with_boost, boost, f64);
176 add_field!(with_max_boost, max_boost, f64);
177 add_field!(with_score_mode, score_mode, ScoreMode);
178 add_field!(with_boost_mode, boost_mode, BoostMode);
179 add_field!(with_min_score, min_score, f64);
180
181 pub fn with_functions<A: Into<Vec<Function>>>(mut self, functions: A) -> Self {
182 self.functions = functions.into();
183 self
184 }
185
186 pub fn with_function<A: Into<Function>>(mut self, function: A) -> Self {
187 self.functions = vec![function.into()];
188 self
189 }
190
191 build!(FunctionScore);
192}
193
194#[derive(Debug, Default, Serialize)]
196pub struct BoostingQuery {
197 #[serde(skip_serializing_if = "ShouldSkip::should_skip")]
198 positive: Option<Query>,
199 #[serde(skip_serializing_if = "ShouldSkip::should_skip")]
200 negative: Option<Query>,
201 #[serde(skip_serializing_if = "ShouldSkip::should_skip")]
202 negative_boost: Option<f64>,
203}
204
205impl Query {
206 pub fn build_boosting() -> BoostingQuery {
207 Default::default()
208 }
209}
210
211impl BoostingQuery {
212 add_field!(with_positive, positive, Query);
213 add_field!(with_negative, negative, Query);
214 add_field!(with_negative_boost, negative_boost, f64);
215
216 build!(Boosting);
217}
218
219#[derive(Debug, Default, Serialize)]
221pub struct IndicesQuery {
222 indices: OneOrMany<String>,
223 query: Query,
224 #[serde(skip_serializing_if = "ShouldSkip::should_skip")]
225 no_match_query: Option<NoMatchQuery>,
226}
227
228impl Query {
229 pub fn build_indices<A, B>(indices: A, query: B) -> IndicesQuery
230 where
231 A: Into<OneOrMany<String>>,
232 B: Into<Query>,
233 {
234 IndicesQuery {
235 indices: indices.into(),
236 query: query.into(),
237 ..Default::default()
238 }
239 }
240}
241
242impl IndicesQuery {
243 add_field!(with_no_match_query, no_match_query, NoMatchQuery);
244
245 build!(Indices);
246}
247
248#[derive(Debug)]
250pub enum NoMatchQuery {
251 None,
252 All,
253 Query(Query),
254}
255
256from_exp!(Query, NoMatchQuery, from, NoMatchQuery::Query(from));
257
258impl Serialize for NoMatchQuery {
259 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
260 where
261 S: Serializer,
262 {
263 use self::NoMatchQuery::*;
264 match self {
265 None => "none".serialize(serializer),
266 All => "all".serialize(serializer),
267 Query(ref q) => q.serialize(serializer),
268 }
269 }
270}