es_public_proxy/
parse.rs

1use serde::{Deserialize, Serialize};
2use std::collections::HashMap;
3
4#[derive(Serialize, Deserialize, Debug)]
5pub struct ApiRequest {
6    pub method: String,
7    pub path_and_query: String,
8    pub body: Option<SearchBody>,
9}
10
11#[derive(Serialize, Deserialize, Debug, Default)]
12#[serde(deny_unknown_fields)]
13pub struct UrlQueryParams {
14    #[serde(skip_serializing_if = "Option::is_none")]
15    pub allow_no_indices: Option<bool>,
16    #[serde(skip_serializing_if = "Option::is_none")]
17    pub allow_partial_search_results: Option<bool>,
18    #[serde(skip_serializing_if = "Option::is_none")]
19    pub batched_reduce_size: Option<u32>,
20    #[serde(skip_serializing_if = "Option::is_none")]
21    pub ccs_minimize_roundtrips: Option<bool>,
22    #[serde(skip_serializing_if = "Option::is_none")]
23    pub docvalue_fields: Option<String>, // array of strings, comma-separated
24    #[serde(skip_serializing_if = "Option::is_none")]
25    pub expand_wildcards: Option<String>,
26    #[serde(skip_serializing_if = "Option::is_none")]
27    pub explain: Option<bool>,
28    #[serde(skip_serializing_if = "Option::is_none")]
29    pub from: Option<u32>,
30    #[serde(skip_serializing_if = "Option::is_none")]
31    pub ignore_throttled: Option<bool>,
32    #[serde(skip_serializing_if = "Option::is_none")]
33    pub ignore_unavailable: Option<bool>,
34    #[serde(skip_serializing_if = "Option::is_none")]
35    pub max_concurrent_shard_requests: Option<u32>,
36    #[serde(skip_serializing_if = "Option::is_none")]
37    pub pre_filter_shard_size: Option<u32>,
38    #[serde(skip_serializing_if = "Option::is_none")]
39    pub preference: Option<String>,
40    #[serde(skip_serializing_if = "Option::is_none")]
41    pub q: Option<String>,
42    #[serde(skip_serializing_if = "Option::is_none")]
43    pub request_cache: Option<bool>,
44    #[serde(skip_serializing_if = "Option::is_none")]
45    pub rest_total_hits_as_int: Option<bool>,
46    #[serde(skip_serializing_if = "Option::is_none")]
47    pub routing: Option<String>,
48    #[serde(skip_serializing_if = "Option::is_none")]
49    pub scroll: Option<String>, // string is "time value"
50    #[serde(skip_serializing_if = "Option::is_none")]
51    pub search_type: Option<String>,
52    #[serde(skip_serializing_if = "Option::is_none")]
53    pub seq_no_primary_term: Option<bool>,
54    #[serde(skip_serializing_if = "Option::is_none")]
55    pub size: Option<u32>,
56    #[serde(skip_serializing_if = "Option::is_none")]
57    pub sort: Option<String>, // array of strings, comma-separated
58    #[serde(skip_serializing_if = "Option::is_none")]
59    pub _source: Option<bool>, // TODO: bool or string
60    #[serde(skip_serializing_if = "Option::is_none")]
61    pub _source_excludes: Option<String>, // array of strings, comma-separated
62    #[serde(skip_serializing_if = "Option::is_none")]
63    pub _source_includes: Option<String>, // array of strings, comma-separated
64    #[serde(skip_serializing_if = "Option::is_none")]
65    pub stats: Option<String>,
66    #[serde(skip_serializing_if = "Option::is_none")]
67    pub stored_fields: Option<String>, // array of strings, comma-separated
68    #[serde(skip_serializing_if = "Option::is_none")]
69    pub suggest_field: Option<String>,
70    #[serde(skip_serializing_if = "Option::is_none")]
71    pub suggest_text: Option<String>,
72    #[serde(skip_serializing_if = "Option::is_none")]
73    pub terminate_after: Option<u32>,
74    #[serde(skip_serializing_if = "Option::is_none")]
75    pub timeout: Option<String>, // string is "time units"
76    #[serde(skip_serializing_if = "Option::is_none")]
77    pub track_scores: Option<bool>,
78    #[serde(skip_serializing_if = "Option::is_none")]
79    pub track_total_hits: Option<bool>, // XXX: bool or integer
80    #[serde(skip_serializing_if = "Option::is_none")]
81    pub typed_keys: Option<bool>,
82    #[serde(skip_serializing_if = "Option::is_none")]
83    pub version: Option<bool>,
84
85    // additional generic params
86    #[serde(skip_serializing_if = "Option::is_none")]
87    pub human: Option<bool>,
88    #[serde(skip_serializing_if = "Option::is_none")]
89    pub pretty: Option<bool>,
90    #[serde(skip_serializing_if = "Option::is_none")]
91    pub filter_path: Option<String>,
92    #[serde(skip_serializing_if = "Option::is_none")]
93    pub error_trace: Option<bool>,
94}
95
96// https://www.elastic.co/guide/en/elasticsearch/reference/current/search-search.html
97#[derive(Serialize, Deserialize, Debug)]
98#[serde(deny_unknown_fields)]
99pub struct SearchBody {
100    #[serde(skip_serializing_if = "Option::is_none")]
101    pub query: Option<ApiQuery>,
102    #[serde(skip_serializing_if = "Option::is_none")]
103    pub highlight: Option<ApiHighlight>,
104    #[serde(skip_serializing_if = "Option::is_none")]
105    pub collapse: Option<ApiCollapse>,
106    #[serde(skip_serializing_if = "Option::is_none")]
107    pub post_filter: Option<ApiQuery>, // TODO: leaf query only?
108    #[serde(skip_serializing_if = "Option::is_none")]
109    pub rescore: Option<ApiRescore>, // TODO: single or an array of rescore objects
110    // script_fields disabled
111    #[serde(skip_serializing_if = "Option::is_none")]
112    pub aggs: Option<HashMap<String, ApiAggregation>>,
113    #[serde(skip_serializing_if = "Option::is_none")]
114    pub aggregations: Option<HashMap<String, ApiAggregation>>,
115
116    // https://www.elastic.co/guide/en/elasticsearch/reference/current/sort-search-results.html
117    #[serde(skip_serializing_if = "Option::is_none")]
118    pub sort: Option<SortSingleOrVec>,
119
120    #[serde(skip_serializing_if = "Option::is_none")]
121    pub slice: Option<ApiSlice>,
122    #[serde(skip_serializing_if = "Option::is_none")]
123    pub stored_fields: Option<String>, // array of strings, or "_none_"
124
125    // overlap with URL query parameters
126    #[serde(skip_serializing_if = "Option::is_none")]
127    pub docvalue_fields: Option<Vec<DocValOrString>>,
128    #[serde(skip_serializing_if = "Option::is_none")]
129    pub explain: Option<bool>,
130    #[serde(skip_serializing_if = "Option::is_none")]
131    pub from: Option<u32>,
132    #[serde(skip_serializing_if = "Option::is_none")]
133    pub min_score: Option<Num>,
134    #[serde(skip_serializing_if = "Option::is_none")]
135    pub seq_no_primary_term: Option<bool>,
136    #[serde(skip_serializing_if = "Option::is_none")]
137    pub size: Option<u32>,
138    #[serde(skip_serializing_if = "Option::is_none")]
139    pub _source: Option<bool>, // XXX: bool, string, or object
140    #[serde(skip_serializing_if = "Option::is_none")]
141    pub terminate_after: Option<u32>,
142    #[serde(skip_serializing_if = "Option::is_none")]
143    pub timeout: Option<String>, // string is "time units"
144    #[serde(skip_serializing_if = "Option::is_none")]
145    pub track_total_hits: Option<bool>,
146}
147
148#[derive(Serialize, Deserialize, Debug)]
149#[serde(deny_unknown_fields)]
150pub struct ScrollBody {
151    pub scroll_id: StringOrArray,
152    #[serde(skip_serializing_if = "Option::is_none")]
153    pub scroll: Option<String>,
154}
155
156#[derive(Serialize, Deserialize, Debug)]
157#[serde(deny_unknown_fields)]
158pub struct ApiSlice {
159    id: u32,
160    max: u32,
161    #[serde(skip_serializing_if = "Option::is_none")]
162    field: Option<String>,
163}
164
165#[derive(Serialize, Deserialize, Debug)]
166#[serde(deny_unknown_fields)]
167pub struct ApiRescore {
168    #[serde(skip_serializing_if = "Option::is_none")]
169    pub query: Option<ApiQuery>,
170    #[serde(skip_serializing_if = "Option::is_none")]
171    pub window_size: Option<u32>,
172}
173
174// TODO: could revert to having query types as an enum, with flattening
175#[derive(Serialize, Deserialize, Debug)]
176#[serde(deny_unknown_fields)]
177pub struct ApiQuery {
178    // compound queries
179    #[serde(rename = "bool")]
180    #[serde(skip_serializing_if = "Option::is_none")]
181    bool_query: Option<BoolQuery>,
182    #[serde(skip_serializing_if = "Option::is_none")]
183    boosting: Option<BoostingQuery>,
184    #[serde(skip_serializing_if = "Option::is_none")]
185    constant_score: Option<ConstantScoreQuery>,
186
187    // fulltext (leaf) queries
188    #[serde(rename = "match")]
189    #[serde(skip_serializing_if = "Option::is_none")]
190    match_query: Option<HashMap<String, MatchQueryOrString>>,
191    #[serde(skip_serializing_if = "Option::is_none")]
192    match_phrase: Option<HashMap<String, QueryFieldOrString>>,
193    #[serde(skip_serializing_if = "Option::is_none")]
194    multi_match: Option<MultiMatchQuery>,
195    #[serde(skip_serializing_if = "Option::is_none")]
196    query_string: Option<QueryStringQuery>,
197    #[serde(skip_serializing_if = "Option::is_none")]
198    simple_query_string: Option<QueryStringQuery>,
199
200    // term-level (leaf) queries
201    #[serde(skip_serializing_if = "Option::is_none")]
202    exists: Option<SimpleFieldOrString>,
203    #[serde(skip_serializing_if = "Option::is_none")]
204    match_all: Option<SimpleBoost>,
205    #[serde(skip_serializing_if = "Option::is_none")]
206    match_none: Option<SimpleBoost>,
207    #[serde(skip_serializing_if = "Option::is_none")]
208    ids: Option<IdsQuery>,
209    #[serde(skip_serializing_if = "Option::is_none")]
210    wildcard: Option<HashMap<String, TermQueryOrValue>>, // also works for wildcard
211    #[serde(skip_serializing_if = "Option::is_none")]
212    prefix: Option<HashMap<String, TermQueryOrValue>>, // also works for prefix query
213    #[serde(skip_serializing_if = "Option::is_none")]
214    range: Option<HashMap<String, RangeQuery>>,
215    #[serde(skip_serializing_if = "Option::is_none")]
216    term: Option<HashMap<String, TermQueryOrValue>>,
217    #[serde(skip_serializing_if = "Option::is_none")]
218    // TODO: boost in terms query
219    terms: Option<HashMap<String, Vec<String>>>,
220
221    // other
222    #[serde(skip_serializing_if = "Option::is_none")]
223    nested: Option<NestedQuery>,
224    #[serde(skip_serializing_if = "Option::is_none")]
225    rescore_query: Option<Box<ApiQuery>>,
226
227    // fields as part of a rescore query
228    #[serde(skip_serializing_if = "Option::is_none")]
229    score_mode: Option<String>,
230    #[serde(skip_serializing_if = "Option::is_none")]
231    query_weight: Option<Num>,
232    #[serde(skip_serializing_if = "Option::is_none")]
233    rescore_query_weight: Option<Num>,
234}
235
236#[derive(Serialize, Deserialize, Debug)]
237#[serde(deny_unknown_fields)]
238#[serde(untagged)]
239pub enum ApiQueryOrArray {
240    Single(ApiQuery),
241    Array(Vec<ApiQuery>),
242}
243
244#[derive(Serialize, Deserialize, Debug)]
245#[serde(deny_unknown_fields)]
246#[serde(untagged)]
247pub enum ApiQueryNamedOrArray {
248    Named(HashMap<String, ApiQuery>),
249    Array(Vec<ApiQuery>),
250}
251
252#[derive(Serialize, Deserialize, Debug)]
253#[serde(deny_unknown_fields)]
254pub struct ApiHighlight {
255    // TODO: fields could also be an array of strings?
256    fields: HashMap<String, HighlightField>,
257
258    #[serde(flatten)]
259    settings: HighlightField,
260}
261
262#[derive(Serialize, Deserialize, Debug)]
263#[serde(deny_unknown_fields)]
264#[serde(untagged)]
265pub enum SortMapValue {
266    String(String),
267    Object {
268        order: String,
269        #[serde(skip_serializing_if = "Option::is_none")]
270        mode: Option<String>,
271    },
272}
273
274#[derive(Serialize, Deserialize, Debug)]
275#[serde(deny_unknown_fields)]
276#[serde(untagged)]
277pub enum SortElement {
278    String(String),
279    Object(HashMap<String, SortMapValue>),
280}
281
282#[derive(Serialize, Deserialize, Debug)]
283#[serde(deny_unknown_fields)]
284#[serde(untagged)]
285pub enum SortSingleOrVec {
286    Single(String),
287    Vec(Vec<SortElement>),
288}
289
290#[derive(Serialize, Deserialize, Debug)]
291#[serde(deny_unknown_fields)]
292#[serde(untagged)]
293pub enum DocValOrString {
294    String(String),
295    Object {
296        field: String,
297        #[serde(skip_serializing_if = "Option::is_none")]
298        format: Option<String>,
299    },
300}
301
302#[derive(Serialize, Deserialize, Debug)]
303#[serde(deny_unknown_fields)]
304#[serde(untagged)]
305pub enum MatchQueryOrString {
306    Object(MatchQuery),
307    String(String),
308}
309
310// https://www.elastic.co/guide/en/elasticsearch/reference/7.9/query-dsl-match-query.html
311#[derive(Serialize, Deserialize, Debug)]
312#[serde(deny_unknown_fields)]
313pub struct MatchQuery {
314    query: String,
315
316    #[serde(flatten)]
317    options: MatchOptions,
318}
319
320// https://www.elastic.co/guide/en/elasticsearch/reference/7.9/query-dsl-multi-match-query.html
321#[derive(Serialize, Deserialize, Debug)]
322#[serde(deny_unknown_fields)]
323pub struct MultiMatchQuery {
324    query: String,
325    fields: Vec<String>,
326    #[serde(skip_serializing_if = "Option::is_none")]
327    #[serde(rename = "type")]
328    query_type: Option<String>,
329    #[serde(skip_serializing_if = "Option::is_none")]
330    tie_breaker: Option<Num>,
331    #[serde(flatten)]
332    options: MatchOptions,
333}
334
335#[derive(Serialize, Deserialize, Debug)]
336#[serde(deny_unknown_fields)]
337pub struct MatchOptions {
338    #[serde(skip_serializing_if = "Option::is_none")]
339    analyzer: Option<String>,
340    #[serde(skip_serializing_if = "Option::is_none")]
341    auto_generate_synonyms_phrase_query: Option<bool>,
342    #[serde(skip_serializing_if = "Option::is_none")]
343    fuzziness: Option<String>,
344    #[serde(skip_serializing_if = "Option::is_none")]
345    max_expansions: Option<u32>,
346    #[serde(skip_serializing_if = "Option::is_none")]
347    prefix_length: Option<u32>,
348    #[serde(skip_serializing_if = "Option::is_none")]
349    fuzzy_transpositions: Option<bool>,
350    #[serde(skip_serializing_if = "Option::is_none")]
351    fuzzy_rewrite: Option<String>,
352    #[serde(skip_serializing_if = "Option::is_none")]
353    lenient: Option<bool>,
354    #[serde(skip_serializing_if = "Option::is_none")]
355    operator: Option<String>,
356    #[serde(skip_serializing_if = "Option::is_none")]
357    minimum_should_match: Option<StringOrNum>,
358    #[serde(skip_serializing_if = "Option::is_none")]
359    zero_terms_query: Option<String>,
360}
361
362// https://www.elastic.co/guide/en/elasticsearch/reference/7.9/query-dsl-query-string-query.html
363#[derive(Serialize, Deserialize, Debug)]
364#[serde(deny_unknown_fields)]
365pub struct QueryStringQuery {
366    query: String,
367    #[serde(skip_serializing_if = "Option::is_none")]
368    #[serde(rename = "type")]
369    query_type: Option<String>,
370    #[serde(skip_serializing_if = "Option::is_none")]
371    default_field: Option<String>,
372    #[serde(skip_serializing_if = "Option::is_none")]
373    allow_leading_wildcard: Option<bool>,
374    #[serde(skip_serializing_if = "Option::is_none")]
375    analyze_wildcard: Option<bool>,
376    #[serde(skip_serializing_if = "Option::is_none")]
377    analyzer: Option<String>,
378    #[serde(skip_serializing_if = "Option::is_none")]
379    auto_generate_synonyms_phrase_query: Option<bool>,
380    #[serde(skip_serializing_if = "Option::is_none")]
381    boost: Option<Num>,
382    #[serde(skip_serializing_if = "Option::is_none")]
383    default_operator: Option<String>,
384    #[serde(skip_serializing_if = "Option::is_none")]
385    enable_position_increments: Option<bool>,
386    #[serde(skip_serializing_if = "Option::is_none")]
387    fields: Option<Vec<String>>,
388    #[serde(skip_serializing_if = "Option::is_none")]
389    fuzziness: Option<String>,
390    #[serde(skip_serializing_if = "Option::is_none")]
391    fuzzy_max_expansions: Option<u32>,
392    #[serde(skip_serializing_if = "Option::is_none")]
393    fuzzy_prefix_length: Option<u32>,
394    #[serde(skip_serializing_if = "Option::is_none")]
395    fuzzy_transpositions: Option<bool>,
396    #[serde(skip_serializing_if = "Option::is_none")]
397    lenient: Option<bool>,
398    #[serde(skip_serializing_if = "Option::is_none")]
399    max_determinized_states: Option<u32>,
400    #[serde(skip_serializing_if = "Option::is_none")]
401    minimum_should_match: Option<StringOrNum>,
402    #[serde(skip_serializing_if = "Option::is_none")]
403    quote_analyzer: Option<String>,
404    #[serde(skip_serializing_if = "Option::is_none")]
405    phrase_slop: Option<u32>,
406    #[serde(skip_serializing_if = "Option::is_none")]
407    quote_field_suffix: Option<String>,
408    #[serde(skip_serializing_if = "Option::is_none")]
409    rewrite: Option<String>,
410    #[serde(skip_serializing_if = "Option::is_none")]
411    time_zone: Option<String>,
412}
413
414#[derive(Serialize, Deserialize, Debug)]
415#[serde(deny_unknown_fields)]
416pub struct SimpleBoost {
417    #[serde(skip_serializing_if = "Option::is_none")]
418    boost: Option<Num>,
419}
420
421#[derive(Serialize, Deserialize, Debug)]
422#[serde(deny_unknown_fields)]
423pub struct IdsQuery {
424    values: Vec<String>,
425}
426
427#[derive(Serialize, Deserialize, Debug)]
428#[serde(deny_unknown_fields)]
429#[serde(untagged)]
430pub enum TermQueryOrValue {
431    String(String),
432    Int(u64),
433    Float(f64),
434    Boolean(bool),
435    Object(TermQuery),
436}
437
438#[derive(Serialize, Deserialize, Debug)]
439#[serde(deny_unknown_fields)]
440pub struct TermQuery {
441    value: StringOrNumOrBool,
442    #[serde(skip_serializing_if = "Option::is_none")]
443    rewrite: Option<String>,
444    #[serde(skip_serializing_if = "Option::is_none")]
445    boost: Option<Num>,
446}
447
448#[derive(Serialize, Deserialize, Debug)]
449#[serde(deny_unknown_fields)]
450#[serde(untagged)]
451pub enum StringOrNum {
452    String(String),
453    Int(u64),
454    Float(f64),
455}
456
457#[derive(Serialize, Deserialize, Debug)]
458#[serde(deny_unknown_fields)]
459#[serde(untagged)]
460pub enum StringOrNumOrBool {
461    String(String),
462    Int(u64),
463    Float(f64),
464    Boolean(bool),
465}
466
467#[derive(Serialize, Deserialize, Debug)]
468#[serde(deny_unknown_fields)]
469#[serde(untagged)]
470pub enum Num {
471    Int(u64),
472    Float(f64),
473}
474
475#[derive(Serialize, Deserialize, Debug)]
476#[serde(deny_unknown_fields)]
477#[serde(untagged)]
478pub enum StringOrArray {
479    String(String),
480    Array(Vec<String>),
481}
482
483#[derive(Serialize, Deserialize, Debug)]
484#[serde(deny_unknown_fields)]
485pub struct RangeQuery {
486    #[serde(skip_serializing_if = "Option::is_none")]
487    gt: Option<StringOrNum>,
488    #[serde(skip_serializing_if = "Option::is_none")]
489    gte: Option<StringOrNum>,
490    #[serde(skip_serializing_if = "Option::is_none")]
491    lt: Option<StringOrNum>,
492    #[serde(skip_serializing_if = "Option::is_none")]
493    lte: Option<StringOrNum>,
494    #[serde(skip_serializing_if = "Option::is_none")]
495    format: Option<String>,
496    #[serde(skip_serializing_if = "Option::is_none")]
497    relation: Option<String>,
498    #[serde(skip_serializing_if = "Option::is_none")]
499    timezone: Option<String>,
500    #[serde(skip_serializing_if = "Option::is_none")]
501    boost: Option<Num>,
502}
503
504#[derive(Serialize, Deserialize, Debug)]
505#[serde(deny_unknown_fields)]
506#[serde(untagged)]
507pub enum QueryFieldOrString {
508    Object(QueryField),
509    String(String),
510}
511
512#[derive(Serialize, Deserialize, Debug)]
513#[serde(deny_unknown_fields)]
514pub struct QueryField {
515    query: String,
516    #[serde(skip_serializing_if = "Option::is_none")]
517    fuzziness: Option<String>,
518    #[serde(skip_serializing_if = "Option::is_none")]
519    slop: Option<u32>,
520    #[serde(skip_serializing_if = "Option::is_none")]
521    boost: Option<Num>,
522}
523
524#[derive(Serialize, Deserialize, Debug)]
525#[serde(deny_unknown_fields)]
526pub struct BoolQuery {
527    #[serde(skip_serializing_if = "Option::is_none")]
528    must: Option<Box<ApiQueryOrArray>>,
529    #[serde(skip_serializing_if = "Option::is_none")]
530    filter: Option<Box<ApiQueryOrArray>>,
531    #[serde(skip_serializing_if = "Option::is_none")]
532    should: Option<Box<ApiQueryOrArray>>,
533    #[serde(skip_serializing_if = "Option::is_none")]
534    must_not: Option<Box<ApiQueryOrArray>>,
535    #[serde(skip_serializing_if = "Option::is_none")]
536    minimum_should_match: Option<StringOrNum>,
537    #[serde(skip_serializing_if = "Option::is_none")]
538    boost: Option<Num>,
539}
540
541#[derive(Serialize, Deserialize, Debug)]
542#[serde(deny_unknown_fields)]
543pub struct NestedQuery {
544    path: String,
545    query: Box<ApiQuery>,
546    #[serde(skip_serializing_if = "Option::is_none")]
547    score_mode: Option<String>,
548    #[serde(skip_serializing_if = "Option::is_none")]
549    ignore_unmapped: Option<bool>,
550    #[serde(skip_serializing_if = "Option::is_none")]
551    inner_hits: Option<InnerHitsOneOrMore>,
552}
553
554#[derive(Serialize, Deserialize, Debug)]
555#[serde(deny_unknown_fields)]
556pub struct BoostingQuery {
557    positive: Box<ApiQuery>,
558    negative: Box<ApiQuery>,
559    negative_boost: Num,
560}
561
562#[derive(Serialize, Deserialize, Debug)]
563#[serde(deny_unknown_fields)]
564pub struct ConstantScoreQuery {
565    filter: Box<ApiQueryOrArray>,
566    #[serde(skip_serializing_if = "Option::is_none")]
567    boost: Option<Num>,
568}
569
570// https://www.elastic.co/guide/en/elasticsearch/reference/current/highlighting.html
571#[derive(Serialize, Deserialize, Debug)]
572#[serde(deny_unknown_fields)]
573pub struct HighlightField {
574    #[serde(skip_serializing_if = "Option::is_none")]
575    boundary_chars: Option<String>,
576    #[serde(skip_serializing_if = "Option::is_none")]
577    boundary_max_scan: Option<u32>,
578    #[serde(skip_serializing_if = "Option::is_none")]
579    boundary_scanner: Option<String>,
580    #[serde(skip_serializing_if = "Option::is_none")]
581    boundary_scanner_locale: Option<String>,
582    #[serde(skip_serializing_if = "Option::is_none")]
583    encoder: Option<String>,
584    #[serde(skip_serializing_if = "Option::is_none")]
585    force_source: Option<bool>,
586    #[serde(skip_serializing_if = "Option::is_none")]
587    fragmenter: Option<String>,
588    #[serde(skip_serializing_if = "Option::is_none")]
589    fragment_offset: Option<u32>,
590    #[serde(skip_serializing_if = "Option::is_none")]
591    fragment_size: Option<u32>,
592    #[serde(skip_serializing_if = "Option::is_none")]
593    highlight_query: Option<ApiQuery>,
594    #[serde(skip_serializing_if = "Option::is_none")]
595    matched_fields: Option<Vec<String>>,
596    #[serde(skip_serializing_if = "Option::is_none")]
597    no_match_size: Option<u32>,
598    #[serde(skip_serializing_if = "Option::is_none")]
599    number_of_fragments: Option<u32>,
600    #[serde(skip_serializing_if = "Option::is_none")]
601    order: Option<String>,
602    #[serde(skip_serializing_if = "Option::is_none")]
603    phrase_limit: Option<u32>,
604    #[serde(skip_serializing_if = "Option::is_none")]
605    pre_tags: Option<Vec<String>>,
606    #[serde(skip_serializing_if = "Option::is_none")]
607    post_tags: Option<Vec<String>>,
608    #[serde(skip_serializing_if = "Option::is_none")]
609    require_field_match: Option<bool>,
610    #[serde(skip_serializing_if = "Option::is_none")]
611    tags_schema: Option<String>,
612    #[serde(rename = "type")]
613    #[serde(skip_serializing_if = "Option::is_none")]
614    highlight_type: Option<String>,
615}
616
617#[derive(Serialize, Deserialize, Debug)]
618#[serde(deny_unknown_fields)]
619#[serde(untagged)]
620pub enum SimpleFieldOrString {
621    String(String),
622    Object { field: String },
623}
624
625#[derive(Serialize, Deserialize, Debug)]
626#[serde(deny_unknown_fields)]
627pub struct ApiCollapse {
628    field: String,
629    #[serde(skip_serializing_if = "Option::is_none")]
630    inner_hits: Option<InnerHitsOneOrMore>,
631}
632
633#[derive(Serialize, Deserialize, Debug)]
634#[serde(deny_unknown_fields)]
635#[serde(untagged)]
636pub enum InnerHitsOneOrMore {
637    Single(InnerHits),
638    Multiple(Vec<InnerHits>),
639}
640
641#[derive(Serialize, Deserialize, Debug)]
642#[serde(deny_unknown_fields)]
643pub struct InnerHits {
644    #[serde(skip_serializing_if = "Option::is_none")]
645    from: Option<u32>,
646    #[serde(skip_serializing_if = "Option::is_none")]
647    size: Option<u32>,
648    #[serde(skip_serializing_if = "Option::is_none")]
649    sort: Option<SortSingleOrVec>,
650    #[serde(skip_serializing_if = "Option::is_none")]
651    name: Option<String>,
652    #[serde(skip_serializing_if = "Option::is_none")]
653    collapse: Option<Box<ApiCollapse>>,
654}
655
656#[derive(Serialize, Deserialize, Debug)]
657#[serde(deny_unknown_fields)]
658pub struct ApiAggregation {
659    // bucket type aggregations
660    #[serde(skip_serializing_if = "Option::is_none")]
661    nested: Option<NestedAggregation>,
662    #[serde(skip_serializing_if = "Option::is_none")]
663    filter: Option<ApiQuery>,
664    #[serde(skip_serializing_if = "Option::is_none")]
665    filters: Option<FiltersAggregation>,
666    #[serde(skip_serializing_if = "Option::is_none")]
667    composite: Option<CompositeAggregation>,
668    #[serde(skip_serializing_if = "Option::is_none")]
669    histogram: Option<SimpleAggregation>,
670    #[serde(skip_serializing_if = "Option::is_none")]
671    date_histogram: Option<DateHistogramAggregation>,
672    #[serde(skip_serializing_if = "Option::is_none")]
673    terms: Option<TermsAggregation>,
674    #[serde(skip_serializing_if = "Option::is_none")]
675    significant_terms: Option<SimpleAggregation>,
676
677    // metrics type aggregations
678    #[serde(skip_serializing_if = "Option::is_none")]
679    avg: Option<SimpleAggregation>,
680    #[serde(skip_serializing_if = "Option::is_none")]
681    min: Option<SimpleAggregation>,
682    #[serde(skip_serializing_if = "Option::is_none")]
683    max: Option<SimpleAggregation>,
684    #[serde(skip_serializing_if = "Option::is_none")]
685    sum: Option<SimpleAggregation>,
686    #[serde(skip_serializing_if = "Option::is_none")]
687    value_count: Option<SimpleAggregation>,
688    #[serde(skip_serializing_if = "Option::is_none")]
689    stats: Option<SimpleAggregation>,
690    #[serde(skip_serializing_if = "Option::is_none")]
691    percentiles: Option<SimpleAggregation>,
692
693    // nested aggregations
694    #[serde(skip_serializing_if = "Option::is_none")]
695    aggs: Option<HashMap<String, Box<ApiAggregation>>>,
696    #[serde(skip_serializing_if = "Option::is_none")]
697    aggregations: Option<HashMap<String, Box<ApiAggregation>>>,
698}
699
700#[derive(Serialize, Deserialize, Debug)]
701#[serde(deny_unknown_fields)]
702pub struct NestedAggregation {
703    path: String,
704}
705
706#[derive(Serialize, Deserialize, Debug)]
707#[serde(deny_unknown_fields)]
708pub struct SimpleAggregation {
709    field: String,
710    #[serde(skip_serializing_if = "Option::is_none")]
711    interval: Option<StringOrNum>,
712    #[serde(skip_serializing_if = "Option::is_none")]
713    missing: Option<StringOrNum>,
714    #[serde(skip_serializing_if = "Option::is_none")]
715    missing_bucket: Option<bool>,
716    #[serde(skip_serializing_if = "Option::is_none")]
717    keyed: Option<bool>,
718}
719
720#[derive(Serialize, Deserialize, Debug)]
721#[serde(deny_unknown_fields)]
722pub struct DateHistogramAggregation {
723    field: String,
724    #[serde(skip_serializing_if = "Option::is_none")]
725    fixed_interval: Option<String>,
726    #[serde(skip_serializing_if = "Option::is_none")]
727    calendar_interval: Option<String>,
728    #[serde(skip_serializing_if = "Option::is_none")]
729    format: Option<String>,
730    #[serde(skip_serializing_if = "Option::is_none")]
731    time_zone: Option<String>,
732    #[serde(skip_serializing_if = "Option::is_none")]
733    offset: Option<String>,
734    #[serde(skip_serializing_if = "Option::is_none")]
735    order: Option<SortElement>,
736    #[serde(skip_serializing_if = "Option::is_none")]
737    keyed: Option<bool>,
738    #[serde(skip_serializing_if = "Option::is_none")]
739    missing: Option<StringOrNum>,
740    #[serde(skip_serializing_if = "Option::is_none")]
741    missing_bucket: Option<bool>,
742}
743
744#[derive(Serialize, Deserialize, Debug)]
745#[serde(deny_unknown_fields)]
746pub struct CompositeAggregation {
747    sources: Vec<HashMap<String, ApiAggregation>>,
748    #[serde(skip_serializing_if = "Option::is_none")]
749    size: Option<u32>,
750    #[serde(skip_serializing_if = "Option::is_none")]
751    after: Option<HashMap<String, StringOrNum>>,
752}
753
754#[derive(Serialize, Deserialize, Debug)]
755#[serde(deny_unknown_fields)]
756pub struct FiltersAggregation {
757    #[serde(skip_serializing_if = "Option::is_none")]
758    other_bucket_key: Option<String>,
759    filters: ApiQueryNamedOrArray,
760}
761
762#[derive(Serialize, Deserialize, Debug)]
763#[serde(deny_unknown_fields)]
764pub struct TermsAggregation {
765    field: String,
766    #[serde(skip_serializing_if = "Option::is_none")]
767    size: Option<u32>,
768    #[serde(skip_serializing_if = "Option::is_none")]
769    shard_size: Option<u32>,
770    #[serde(skip_serializing_if = "Option::is_none")]
771    min_doc_count: Option<u32>,
772    #[serde(skip_serializing_if = "Option::is_none")]
773    show_term_doc_count_error: Option<bool>,
774    #[serde(skip_serializing_if = "Option::is_none")]
775    order: Option<SortElement>,
776    #[serde(skip_serializing_if = "Option::is_none")]
777    include: Option<StringOrArray>,
778    #[serde(skip_serializing_if = "Option::is_none")]
779    exclude: Option<StringOrArray>,
780    #[serde(skip_serializing_if = "Option::is_none")]
781    execution_hint: Option<String>,
782    #[serde(skip_serializing_if = "Option::is_none")]
783    missing: Option<StringOrNum>,
784    #[serde(skip_serializing_if = "Option::is_none")]
785    missing_bucket: Option<bool>,
786}