1use serde::{Serialize, Serializer};
20
21use crate::{
22 json::{NoOuter, ShouldSkip},
23 operations::search::highlight::Highlight,
24 units::JsonVal,
25};
26
27use super::{common::FieldBasedQuery, Flags, Fuzziness, MinimumShouldMatch, Query};
28
29#[derive(Debug, Clone)]
31pub enum MatchType {
32 Boolean,
33 Phrase,
34 PhrasePrefix,
35}
36
37impl Serialize for MatchType {
38 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
39 where
40 S: Serializer,
41 {
42 use self::MatchType::*;
43 match self {
44 Boolean => "boolean",
45 Phrase => "phrase",
46 PhrasePrefix => "phrase_prefix",
47 }
48 .serialize(serializer)
49 }
50}
51
52#[derive(Debug)]
55pub enum ZeroTermsQuery {
56 None,
57 All,
58}
59
60impl Serialize for ZeroTermsQuery {
61 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
62 where
63 S: Serializer,
64 {
65 match self {
66 ZeroTermsQuery::None => "none",
67 ZeroTermsQuery::All => "all",
68 }
69 .serialize(serializer)
70 }
71}
72
73#[derive(Debug, Clone)]
75pub enum MatchQueryType {
76 BestFields,
77 MostFields,
78 CrossFields,
79 Phrase,
80 PhrasePrefix,
81}
82
83impl Serialize for MatchQueryType {
84 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
85 where
86 S: Serializer,
87 {
88 use self::MatchQueryType::*;
89 match self {
90 BestFields => "best_fields",
91 MostFields => "most_fields",
92 CrossFields => "cross_fields",
93 Phrase => "phrase",
94 PhrasePrefix => "phrase_prefix",
95 }
96 .serialize(serializer)
97 }
98}
99
100#[derive(Debug, Serialize)]
103pub struct MatchQuery(FieldBasedQuery<MatchQueryInner, NoOuter>);
104
105#[derive(Debug, Default, Serialize)]
106pub struct MatchQueryInner {
107 query: JsonVal,
108 #[serde(skip_serializing_if = "ShouldSkip::should_skip", rename = "type")]
109 match_type: Option<MatchType>,
110 #[serde(skip_serializing_if = "ShouldSkip::should_skip")]
111 cutoff_frequency: Option<f64>,
112 #[serde(skip_serializing_if = "ShouldSkip::should_skip")]
113 lenient: Option<bool>,
114 #[serde(skip_serializing_if = "ShouldSkip::should_skip")]
115 analyzer: Option<String>,
116 #[serde(skip_serializing_if = "ShouldSkip::should_skip")]
117 boost: Option<f64>,
118 #[serde(skip_serializing_if = "ShouldSkip::should_skip")]
119 operator: Option<String>,
120 #[serde(skip_serializing_if = "ShouldSkip::should_skip")]
121 minimum_should_match: Option<MinimumShouldMatch>,
122 #[serde(skip_serializing_if = "ShouldSkip::should_skip")]
123 fuzziness: Option<Fuzziness>,
124 #[serde(skip_serializing_if = "ShouldSkip::should_skip")]
125 prefix_length: Option<u64>,
126 #[serde(skip_serializing_if = "ShouldSkip::should_skip")]
127 max_expansions: Option<u64>,
128 #[serde(skip_serializing_if = "ShouldSkip::should_skip")]
129 rewrite: Option<String>,
130 #[serde(skip_serializing_if = "ShouldSkip::should_skip")]
131 zero_terms_query: Option<ZeroTermsQuery>,
132 #[serde(skip_serializing_if = "ShouldSkip::should_skip")]
133 slop: Option<i64>,
134 #[serde(skip_serializing_if = "ShouldSkip::should_skip")]
135 highlight: Option<Highlight>,
136}
137
138impl Query {
139 pub fn build_match<A, B>(field: A, query: B) -> MatchQuery
140 where
141 A: Into<String>,
142 B: Into<JsonVal>,
143 {
144 MatchQuery(FieldBasedQuery::new(
145 field.into(),
146 MatchQueryInner {
147 query: query.into(),
148 ..Default::default()
149 },
150 NoOuter,
151 ))
152 }
153}
154
155impl MatchQuery {
156 add_inner_field!(with_type, match_type, MatchType);
157 add_inner_field!(with_cutoff_frequency, cutoff_frequency, f64);
158 add_inner_field!(with_lenient, lenient, bool);
159 add_inner_field!(with_analyzer, analyzer, String);
160 add_inner_field!(with_boost, boost, f64);
161 add_inner_field!(with_operator, operator, String);
162 add_inner_field!(
163 with_minimum_should_match,
164 minimum_should_match,
165 MinimumShouldMatch
166 );
167 add_inner_field!(with_fuzziness, fuzziness, Fuzziness);
168 add_inner_field!(with_prefix_length, prefix_length, u64);
169 add_inner_field!(with_max_expansions, max_expansions, u64);
170 add_inner_field!(with_rewrite, rewrite, String);
171 add_inner_field!(with_zero_terms_query, zero_terms_query, ZeroTermsQuery);
172 add_inner_field!(with_slop, slop, i64);
173 add_inner_field!(with_highlight, highlight, Highlight);
174
175 build!(Match);
176}
177
178#[derive(Debug, Default, Serialize)]
180pub struct MultiMatchQuery {
181 fields: Vec<String>,
182 query: JsonVal,
183 #[serde(skip_serializing_if = "ShouldSkip::should_skip", rename = "type")]
184 match_type: Option<MatchQueryType>,
185 #[serde(skip_serializing_if = "ShouldSkip::should_skip")]
186 tie_breaker: Option<f64>,
187 #[serde(skip_serializing_if = "ShouldSkip::should_skip")]
188 analyzer: Option<String>,
189 #[serde(skip_serializing_if = "ShouldSkip::should_skip")]
190 boost: Option<f64>,
191 #[serde(skip_serializing_if = "ShouldSkip::should_skip")]
192 operator: Option<String>,
193 #[serde(skip_serializing_if = "ShouldSkip::should_skip")]
194 minimum_should_match: Option<MinimumShouldMatch>,
195 #[serde(skip_serializing_if = "ShouldSkip::should_skip")]
196 fuzziness: Option<Fuzziness>,
197 #[serde(skip_serializing_if = "ShouldSkip::should_skip")]
198 prefix_length: Option<u64>,
199 #[serde(skip_serializing_if = "ShouldSkip::should_skip")]
200 max_expansions: Option<u64>,
201 #[serde(skip_serializing_if = "ShouldSkip::should_skip")]
202 rewrite: Option<String>,
203 #[serde(skip_serializing_if = "ShouldSkip::should_skip")]
204 zero_terms_query: Option<ZeroTermsQuery>,
205 #[serde(skip_serializing_if = "ShouldSkip::should_skip")]
206 cutoff_frequency: Option<f64>,
207 #[serde(skip_serializing_if = "ShouldSkip::should_skip")]
208 slop: Option<i64>,
209 #[serde(skip_serializing_if = "ShouldSkip::should_skip")]
210 highlight: Option<Highlight>,
211}
212
213impl Query {
214 pub fn build_multi_match<A, B>(fields: A, query: B) -> MultiMatchQuery
215 where
216 A: Into<Vec<String>>,
217 B: Into<JsonVal>,
218 {
219 MultiMatchQuery {
220 fields: fields.into(),
221 query: query.into(),
222 ..Default::default()
223 }
224 }
225}
226
227impl MultiMatchQuery {
228 add_field!(with_type, match_type, MatchQueryType);
229 add_field!(with_tie_breaker, tie_breaker, f64);
230 add_field!(with_analyzer, analyzer, String);
231 add_field!(with_boost, boost, f64);
232 add_field!(with_operator, operator, String);
233 add_field!(
234 with_minimum_should_match,
235 minimum_should_match,
236 MinimumShouldMatch
237 );
238 add_field!(with_fuzziness, fuzziness, Fuzziness);
239 add_field!(with_prefix_length, prefix_length, u64);
240 add_field!(with_max_expansions, max_expansions, u64);
241 add_field!(with_rewrite, rewrite, String);
242 add_field!(with_zero_terms_query, zero_terms_query, ZeroTermsQuery);
243 add_field!(with_cutoff_frequency, cutoff_frequency, f64);
244 add_field!(with_slop, slop, i64);
245 add_field!(with_highlight, highlight, Highlight);
246
247 build!(MultiMatch);
248}
249
250#[derive(Debug, Serialize)]
252pub struct CommonQuery(FieldBasedQuery<CommonQueryInner, NoOuter>);
253
254#[derive(Debug, Default, Serialize)]
255pub struct CommonQueryInner {
256 query: JsonVal,
257 #[serde(skip_serializing_if = "ShouldSkip::should_skip")]
258 cutoff_frequency: Option<f64>,
259 #[serde(skip_serializing_if = "ShouldSkip::should_skip")]
260 low_freq_operator: Option<String>,
261 #[serde(skip_serializing_if = "ShouldSkip::should_skip")]
262 high_freq_operator: Option<String>,
263 #[serde(skip_serializing_if = "ShouldSkip::should_skip")]
264 minimum_should_match: Option<MinimumShouldMatch>,
265 #[serde(skip_serializing_if = "ShouldSkip::should_skip")]
266 boost: Option<f64>,
267 #[serde(skip_serializing_if = "ShouldSkip::should_skip")]
268 analyzer: Option<String>,
269 #[serde(skip_serializing_if = "ShouldSkip::should_skip")]
270 disable_coord: Option<bool>,
271}
272
273impl Query {
274 pub fn build_common<A>(query: A) -> CommonQuery
275 where
276 A: Into<JsonVal>,
277 {
278 CommonQuery(FieldBasedQuery::new(
279 "body".to_owned(),
280 CommonQueryInner {
281 query: query.into(),
282 ..Default::default()
283 },
284 NoOuter,
285 ))
286 }
287}
288
289impl CommonQuery {
290 add_inner_field!(with_cutoff_frequency, cutoff_frequency, f64);
291 add_inner_field!(with_low_freq_operator, low_freq_operator, String);
292 add_inner_field!(with_high_freq_operator, high_freq_operator, String);
293 add_inner_field!(
294 with_minimum_should_match,
295 minimum_should_match,
296 MinimumShouldMatch
297 );
298 add_inner_field!(with_boost, boost, f64);
299 add_inner_field!(with_analyzer, analyzer, String);
300 add_inner_field!(with_disable_coord, disable_coord, bool);
301
302 build!(Common);
303}
304
305#[derive(Debug, Default, Serialize)]
307pub struct QueryStringQuery {
308 query: String,
309 #[serde(skip_serializing_if = "ShouldSkip::should_skip")]
310 default_field: Option<String>,
311 #[serde(skip_serializing_if = "ShouldSkip::should_skip")]
312 fields: Option<Vec<String>>,
313 #[serde(skip_serializing_if = "ShouldSkip::should_skip")]
314 default_operator: Option<String>,
315 #[serde(skip_serializing_if = "ShouldSkip::should_skip")]
316 analyzer: Option<String>,
317 #[serde(skip_serializing_if = "ShouldSkip::should_skip")]
318 allow_leading_wildcard: Option<bool>,
319 #[serde(skip_serializing_if = "ShouldSkip::should_skip")]
320 lowercase_expanded_terms: Option<bool>,
321 #[serde(skip_serializing_if = "ShouldSkip::should_skip")]
322 enable_position_increments: Option<bool>,
323 #[serde(skip_serializing_if = "ShouldSkip::should_skip")]
324 fuzzy_max_expansions: Option<u64>,
325 #[serde(skip_serializing_if = "ShouldSkip::should_skip")]
326 fuzziness: Option<Fuzziness>,
327 #[serde(skip_serializing_if = "ShouldSkip::should_skip")]
328 fuzzy_prefix_length: Option<u64>,
329 #[serde(skip_serializing_if = "ShouldSkip::should_skip")]
330 phrase_slop: Option<i64>,
331 #[serde(skip_serializing_if = "ShouldSkip::should_skip")]
332 boost: Option<f64>,
333 #[serde(skip_serializing_if = "ShouldSkip::should_skip")]
334 analyze_wildcard: Option<bool>,
335 #[serde(skip_serializing_if = "ShouldSkip::should_skip")]
336 auto_generate_phrase_queries: Option<bool>,
337 #[serde(skip_serializing_if = "ShouldSkip::should_skip")]
338 max_determined_states: Option<u64>,
339 #[serde(skip_serializing_if = "ShouldSkip::should_skip")]
340 minimum_should_match: Option<MinimumShouldMatch>,
341 #[serde(skip_serializing_if = "ShouldSkip::should_skip")]
342 lenient: Option<bool>,
343 #[serde(skip_serializing_if = "ShouldSkip::should_skip")]
344 locale: Option<String>,
345 #[serde(skip_serializing_if = "ShouldSkip::should_skip")]
346 time_zone: Option<String>,
347 #[serde(skip_serializing_if = "ShouldSkip::should_skip")]
348 use_dis_max: Option<bool>,
349}
350
351impl Query {
352 pub fn build_query_string<A: Into<String>>(query: A) -> QueryStringQuery {
353 QueryStringQuery {
354 query: query.into(),
355 ..Default::default()
356 }
357 }
358}
359
360impl QueryStringQuery {
361 add_field!(with_default_field, default_field, String);
362 add_field!(with_fields, fields, Vec<String>);
363 add_field!(with_default_operator, default_operator, String);
364 add_field!(with_analyzer, analyzer, String);
365 add_field!(with_allow_leading_wildcard, allow_leading_wildcard, bool);
366 add_field!(
367 with_lowercase_expanded_terms,
368 lowercase_expanded_terms,
369 bool
370 );
371 add_field!(
372 with_enable_position_increments,
373 enable_position_increments,
374 bool
375 );
376 add_field!(with_fuzzy_max_expansions, fuzzy_max_expansions, u64);
377 add_field!(with_fuzziness, fuzziness, Fuzziness);
378 add_field!(with_fuzzy_prefix_length, fuzzy_prefix_length, u64);
379 add_field!(with_phrase_slop, phrase_slop, i64);
380 add_field!(with_boost, boost, f64);
381 add_field!(with_analyze_wildcard, analyze_wildcard, bool);
382 add_field!(
383 with_auto_generate_phrase_queries,
384 auto_generate_phrase_queries,
385 bool
386 );
387 add_field!(with_max_determined_states, max_determined_states, u64);
388 add_field!(
389 with_minimum_should_match,
390 minimum_should_match,
391 MinimumShouldMatch
392 );
393 add_field!(with_lenient, lenient, bool);
394 add_field!(with_locale, locale, String);
395 add_field!(with_time_zone, time_zone, String);
396 add_field!(with_use_dis_max, use_dis_max, bool);
397
398 build!(QueryString);
399}
400
401#[derive(Debug)]
403pub enum SimpleQueryStringFlags {
404 All,
405 None,
406 And,
407 Or,
408 Not,
409 Prefix,
410 Phrase,
411 Precedence,
412 Escape,
413 Whitespace,
414 Fuzzy,
415 Near,
416 Slop,
417}
418
419impl AsRef<str> for SimpleQueryStringFlags {
420 fn as_ref(&self) -> &str {
421 match self {
422 SimpleQueryStringFlags::All => "ALL",
423 SimpleQueryStringFlags::None => "NONE",
424 SimpleQueryStringFlags::And => "AND",
425 SimpleQueryStringFlags::Or => "OR",
426 SimpleQueryStringFlags::Not => "NOT",
427 SimpleQueryStringFlags::Prefix => "PREFIX",
428 SimpleQueryStringFlags::Phrase => "PHRASE",
429 SimpleQueryStringFlags::Precedence => "PRECEDENCE",
430 SimpleQueryStringFlags::Escape => "ESCAPE",
431 SimpleQueryStringFlags::Whitespace => "WHITESPACE",
432 SimpleQueryStringFlags::Fuzzy => "FUZZY",
433 SimpleQueryStringFlags::Near => "NEAR",
434 SimpleQueryStringFlags::Slop => "SLOP",
435 }
436 }
437}
438
439#[derive(Debug, Default, Serialize)]
441pub struct SimpleQueryStringQuery {
442 query: String,
443 #[serde(skip_serializing_if = "ShouldSkip::should_skip")]
444 fields: Option<Vec<String>>,
445 #[serde(skip_serializing_if = "ShouldSkip::should_skip")]
446 default_operator: Option<String>,
447 #[serde(skip_serializing_if = "ShouldSkip::should_skip")]
448 analyzer: Option<String>,
449 #[serde(skip_serializing_if = "ShouldSkip::should_skip")]
450 flags: Option<Flags<SimpleQueryStringFlags>>,
451 #[serde(skip_serializing_if = "ShouldSkip::should_skip")]
452 lowercase_expanded_terms: Option<bool>,
453 #[serde(skip_serializing_if = "ShouldSkip::should_skip")]
454 analyze_wildcard: Option<bool>,
455 #[serde(skip_serializing_if = "ShouldSkip::should_skip")]
456 locale: Option<String>,
457 #[serde(skip_serializing_if = "ShouldSkip::should_skip")]
458 lenient: Option<bool>,
459 #[serde(skip_serializing_if = "ShouldSkip::should_skip")]
460 minimum_should_match: Option<MinimumShouldMatch>,
461}
462
463impl Query {
464 pub fn build_simple_query_string<A: Into<String>>(query: A) -> SimpleQueryStringQuery {
465 SimpleQueryStringQuery {
466 query: query.into(),
467 ..Default::default()
468 }
469 }
470}
471
472impl SimpleQueryStringQuery {
473 add_field!(with_fields, fields, Vec<String>);
474 add_field!(with_default_operator, default_operator, String);
475 add_field!(with_analyzer, analyzer, String);
476 add_field!(with_flags, flags, Flags<SimpleQueryStringFlags>);
477 add_field!(
478 with_lowercase_expanded_terms,
479 lowercase_expanded_terms,
480 bool
481 );
482 add_field!(with_analyze_wildcard, analyze_wildcard, bool);
483 add_field!(with_locale, locale, String);
484 add_field!(with_lenient, lenient, bool);
485 add_field!(
486 with_minimum_should_match,
487 minimum_should_match,
488 MinimumShouldMatch
489 );
490
491 build!(SimpleQueryString);
492}