1use serde::{Serialize, Serializer};
20
21use crate::{
22 json::{NoOuter, ShouldSkip},
23 units::{JsonPotential, JsonVal, OneOrMany},
24};
25
26use super::{common::FieldBasedQuery, Flags, Fuzziness, Query};
27
28#[derive(Debug)]
30pub enum Rewrite {
31 ConstantScoreAuto,
32 ScoringBoolean,
33 ConstantScoreBoolean,
34 ConstantScoreFilter,
35 TopTerms(i64),
36 TopTermsBoost(i64),
37 TopTermsBlendedFreqs(i64),
38}
39
40impl Serialize for Rewrite {
41 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
42 where
43 S: Serializer,
44 {
45 use self::Rewrite::*;
46 match self {
47 ConstantScoreAuto => "constant_score_auto".serialize(serializer),
48 ScoringBoolean => "scoring_boolean".serialize(serializer),
49 ConstantScoreBoolean => "constant_score_boolean".serialize(serializer),
50 ConstantScoreFilter => "constant_score_filter".serialize(serializer),
51 TopTerms(n) => format!("top_terms_{}", n).serialize(serializer),
52 TopTermsBoost(n) => format!("top_terms_boost_{}", n).serialize(serializer),
53 TopTermsBlendedFreqs(n) => {
54 format!("top_terms_blended_freqs_{}", n).serialize(serializer)
55 }
56 }
57 }
58}
59
60#[derive(Debug, Default, Serialize)]
62pub struct TermQueryInner {
63 value: JsonVal,
64 #[serde(skip_serializing_if = "ShouldSkip::should_skip")]
65 boost: Option<f64>,
66}
67
68impl TermQueryInner {
69 fn new(value: JsonVal) -> Self {
70 TermQueryInner {
71 value,
72 ..Default::default()
73 }
74 }
75}
76
77#[derive(Debug, Serialize)]
78pub struct TermQuery(FieldBasedQuery<TermQueryInner, NoOuter>);
79
80impl Query {
81 pub fn build_term<A, B>(field: A, value: B) -> TermQuery
82 where
83 A: Into<String>,
84 B: Into<JsonVal>,
85 {
86 TermQuery(FieldBasedQuery::new(
87 field.into(),
88 TermQueryInner::new(value.into()),
89 NoOuter,
90 ))
91 }
92}
93
94impl TermQuery {
95 add_inner_field!(with_boost, boost, f64);
96
97 build!(Term);
98}
99
100#[derive(Debug, Default, Serialize)]
103pub struct TermsQueryLookup {
104 id: JsonVal,
105 #[serde(skip_serializing_if = "ShouldSkip::should_skip")]
106 index: Option<String>,
107 #[serde(skip_serializing_if = "ShouldSkip::should_skip")]
108 doc_type: Option<String>,
109 path: String,
110 #[serde(skip_serializing_if = "ShouldSkip::should_skip")]
111 routing: Option<String>,
112}
113
114impl<'a> TermsQueryLookup {
115 pub fn new<A, B>(id: A, path: B) -> TermsQueryLookup
116 where
117 A: Into<JsonVal>,
118 B: Into<String>,
119 {
120 TermsQueryLookup {
121 id: id.into(),
122 path: path.into(),
123 ..Default::default()
124 }
125 }
126
127 add_field!(with_index, index, String);
128 add_field!(with_type, doc_type, String);
129 add_field!(with_routing, routing, String);
130}
131
132#[derive(Debug)]
134pub enum TermsQueryIn {
135 Values(Vec<JsonVal>),
137
138 Lookup(TermsQueryLookup),
140}
141
142impl Serialize for TermsQueryIn {
144 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
145 where
146 S: Serializer,
147 {
148 match self {
149 TermsQueryIn::Values(ref q) => q.serialize(serializer),
150 TermsQueryIn::Lookup(ref q) => q.serialize(serializer),
151 }
152 }
153}
154
155impl Default for TermsQueryIn {
156 fn default() -> Self {
157 TermsQueryIn::Values(Default::default())
158 }
159}
160
161impl From<TermsQueryLookup> for TermsQueryIn {
162 fn from(from: TermsQueryLookup) -> TermsQueryIn {
163 TermsQueryIn::Lookup(from)
164 }
165}
166
167impl From<Vec<JsonVal>> for TermsQueryIn {
168 fn from(from: Vec<JsonVal>) -> TermsQueryIn {
169 TermsQueryIn::Values(from)
170 }
171}
172
173impl<'a, A> From<&'a [A]> for TermsQueryIn
174where
175 A: JsonPotential,
176{
177 fn from(from: &'a [A]) -> Self {
178 TermsQueryIn::Values(from.iter().map(JsonPotential::to_json_val).collect())
179 }
180}
181
182impl<A> From<Vec<A>> for TermsQueryIn
183where
184 A: JsonPotential,
185{
186 fn from(from: Vec<A>) -> TermsQueryIn {
187 (&from[..]).into()
188 }
189}
190
191#[derive(Debug, Serialize)]
193pub struct TermsQuery(FieldBasedQuery<TermsQueryIn, NoOuter>);
194
195impl Query {
196 pub fn build_terms<A>(field: A) -> TermsQuery
197 where
198 A: Into<String>,
199 {
200 TermsQuery(FieldBasedQuery::new(
201 field.into(),
202 Default::default(),
203 NoOuter,
204 ))
205 }
206}
207
208impl TermsQuery {
209 pub fn with_values<T>(mut self, values: T) -> Self
210 where
211 T: Into<TermsQueryIn>,
212 {
213 self.0.inner = values.into();
214 self
215 }
216
217 build!(Terms);
218}
219
220#[derive(Debug, Default, Serialize)]
224pub struct RangeQueryInner {
225 #[serde(skip_serializing_if = "ShouldSkip::should_skip")]
226 gte: Option<JsonVal>,
227 #[serde(skip_serializing_if = "ShouldSkip::should_skip")]
228 gt: Option<JsonVal>,
229 #[serde(skip_serializing_if = "ShouldSkip::should_skip")]
230 lte: Option<JsonVal>,
231 #[serde(skip_serializing_if = "ShouldSkip::should_skip")]
232 lt: Option<JsonVal>,
233 #[serde(skip_serializing_if = "ShouldSkip::should_skip")]
234 boost: Option<f64>,
235 #[serde(skip_serializing_if = "ShouldSkip::should_skip")]
236 time_zone: Option<String>,
237 #[serde(skip_serializing_if = "ShouldSkip::should_skip")]
238 format: Option<String>,
239}
240
241#[derive(Debug, Serialize)]
242pub struct RangeQuery(FieldBasedQuery<RangeQueryInner, NoOuter>);
243
244impl Query {
245 pub fn build_range<A>(field: A) -> RangeQuery
246 where
247 A: Into<String>,
248 {
249 RangeQuery(FieldBasedQuery::new(
250 field.into(),
251 Default::default(),
252 NoOuter,
253 ))
254 }
255}
256
257impl RangeQuery {
258 add_inner_field!(with_gte, gte, JsonVal);
259 add_inner_field!(with_gt, gt, JsonVal);
260 add_inner_field!(with_lte, lte, JsonVal);
261 add_inner_field!(with_lt, lt, JsonVal);
262 add_inner_field!(with_boost, boost, f64);
263 add_inner_field!(with_time_zone, time_zone, String);
264 add_inner_field!(with_format, format, String);
265
266 build!(Range);
267}
268
269#[derive(Debug, Serialize)]
271pub struct ExistsQuery {
272 field: String,
273}
274
275impl Query {
276 pub fn build_exists<A>(field: A) -> ExistsQuery
277 where
278 A: Into<String>,
279 {
280 ExistsQuery {
281 field: field.into(),
282 }
283 }
284}
285
286impl ExistsQuery {
287 build!(Exists);
288}
289
290#[derive(Debug, Serialize)]
292pub struct PrefixQuery(FieldBasedQuery<PrefixQueryInner, NoOuter>);
293
294#[derive(Debug, Default, Serialize)]
295pub struct PrefixQueryInner {
296 value: String,
297 #[serde(skip_serializing_if = "ShouldSkip::should_skip")]
298 boost: Option<f64>,
299 #[serde(skip_serializing_if = "ShouldSkip::should_skip")]
300 rewrite: Option<Rewrite>,
301}
302
303impl Query {
304 pub fn build_prefix<A, B>(field: A, value: B) -> PrefixQuery
305 where
306 A: Into<String>,
307 B: Into<String>,
308 {
309 PrefixQuery(FieldBasedQuery::new(
310 field.into(),
311 PrefixQueryInner {
312 value: value.into(),
313 ..Default::default()
314 },
315 NoOuter,
316 ))
317 }
318}
319
320impl PrefixQuery {
321 add_inner_field!(with_boost, boost, f64);
322 add_inner_field!(with_rewrite, rewrite, Rewrite);
323
324 build!(Prefix);
325}
326
327#[derive(Debug, Serialize)]
329pub struct WildcardQuery(FieldBasedQuery<WildcardQueryInner, NoOuter>);
330
331#[derive(Debug, Default, Serialize)]
332pub struct WildcardQueryInner {
333 value: String,
334 #[serde(skip_serializing_if = "ShouldSkip::should_skip")]
335 boost: Option<f64>,
336 #[serde(skip_serializing_if = "ShouldSkip::should_skip")]
337 rewrite: Option<Rewrite>,
338}
339
340impl Query {
341 pub fn build_wildcard<A, B>(field: A, value: B) -> WildcardQuery
342 where
343 A: Into<String>,
344 B: Into<String>,
345 {
346 WildcardQuery(FieldBasedQuery::new(
347 field.into(),
348 WildcardQueryInner {
349 value: value.into(),
350 ..Default::default()
351 },
352 NoOuter,
353 ))
354 }
355}
356
357impl WildcardQuery {
358 add_inner_field!(with_boost, boost, f64);
359 add_inner_field!(with_rewrite, rewrite, Rewrite);
360
361 build!(Wildcard);
362}
363
364#[derive(Debug)]
367pub enum RegexpQueryFlags {
368 All,
369 Anystring,
370 Complement,
371 Empty,
372 Intersection,
373 Interval,
374 None,
375}
376
377impl AsRef<str> for RegexpQueryFlags {
378 fn as_ref(&self) -> &str {
379 match self {
380 RegexpQueryFlags::All => "ALL",
381 RegexpQueryFlags::Anystring => "ANYSTRING",
382 RegexpQueryFlags::Complement => "COMPLEMENT",
383 RegexpQueryFlags::Empty => "EMPTY",
384 RegexpQueryFlags::Intersection => "INTERSECTION",
385 RegexpQueryFlags::Interval => "INTERVAL",
386 RegexpQueryFlags::None => "NONE",
387 }
388 }
389}
390
391#[derive(Debug, Serialize)]
393pub struct RegexpQuery(FieldBasedQuery<RegexpQueryInner, NoOuter>);
394
395#[derive(Debug, Default, Serialize)]
396pub struct RegexpQueryInner {
397 value: String,
398 #[serde(skip_serializing_if = "ShouldSkip::should_skip")]
399 boost: Option<f64>,
400 #[serde(skip_serializing_if = "ShouldSkip::should_skip")]
401 flags: Option<Flags<RegexpQueryFlags>>,
402 #[serde(skip_serializing_if = "ShouldSkip::should_skip")]
403 max_determined_states: Option<u64>,
404}
405
406impl Query {
407 pub fn build_query<A, B>(field: A, value: B) -> RegexpQuery
408 where
409 A: Into<String>,
410 B: Into<String>,
411 {
412 RegexpQuery(FieldBasedQuery::new(
413 field.into(),
414 RegexpQueryInner {
415 value: value.into(),
416 ..Default::default()
417 },
418 NoOuter,
419 ))
420 }
421}
422
423impl RegexpQuery {
424 add_inner_field!(with_boost, boost, f64);
425 add_inner_field!(with_flags, flags, Flags<RegexpQueryFlags>);
426 add_inner_field!(with_max_determined_states, max_determined_states, u64);
427
428 build!(Regexp);
429}
430
431#[derive(Debug, Serialize)]
433pub struct FuzzyQuery(FieldBasedQuery<FuzzyQueryInner, NoOuter>);
434
435#[derive(Debug, Default, Serialize)]
436pub struct FuzzyQueryInner {
437 value: String,
438 #[serde(skip_serializing_if = "ShouldSkip::should_skip")]
439 boost: Option<f64>,
440 #[serde(skip_serializing_if = "ShouldSkip::should_skip")]
441 fuzziness: Option<Fuzziness>,
442 #[serde(skip_serializing_if = "ShouldSkip::should_skip")]
443 prefix_length: Option<u64>,
444 #[serde(skip_serializing_if = "ShouldSkip::should_skip")]
445 max_expansions: Option<u64>,
446}
447
448impl Query {
449 pub fn build_fuzzy<A, B>(field: A, value: B) -> FuzzyQuery
450 where
451 A: Into<String>,
452 B: Into<String>,
453 {
454 FuzzyQuery(FieldBasedQuery::new(
455 field.into(),
456 FuzzyQueryInner {
457 value: value.into(),
458 ..Default::default()
459 },
460 NoOuter,
461 ))
462 }
463}
464
465impl FuzzyQuery {
466 add_inner_field!(with_boost, boost, f64);
467 add_inner_field!(with_fuzziness, fuzziness, Fuzziness);
468 add_inner_field!(with_prefix_length, prefix_length, u64);
469 add_inner_field!(with_max_expansions, max_expansions, u64);
470
471 build!(Fuzzy);
472}
473
474#[derive(Debug, Serialize)]
476pub struct TypeQuery {
477 value: String,
478}
479
480impl Query {
481 pub fn build_type<A>(value: A) -> TypeQuery
482 where
483 A: Into<String>,
484 {
485 TypeQuery {
486 value: value.into(),
487 }
488 }
489}
490
491impl TypeQuery {
492 build!(Type);
493}
494
495#[derive(Debug, Default, Serialize)]
497pub struct IdsQuery {
498 #[serde(skip_serializing_if = "ShouldSkip::should_skip")]
499 doc_type: Option<OneOrMany<String>>,
500 values: Vec<JsonVal>,
501}
502
503impl Query {
504 pub fn build_ids<A>(values: A) -> IdsQuery
505 where
506 A: Into<Vec<JsonVal>>,
507 {
508 IdsQuery {
509 values: values.into(),
510 ..Default::default()
511 }
512 }
513}
514
515impl IdsQuery {
516 add_field!(with_type, doc_type, OneOrMany<String>);
517
518 build!(Ids);
519}