elastic_query_builder/aggregation/
stats_aggregation.rs

1use crate::aggregation::AggregationTrait;
2use crate::merge;
3use serde::ser::SerializeStruct;
4use serde::{Serialize, Serializer};
5use serde_json::{json, Value};
6
7#[derive(Default)]
8pub struct StatsAggregation {
9    name: String,
10    value: SumValue,
11    aggregation: Value,
12}
13
14#[derive(Default)]
15struct SumValue {
16    field: String,
17    script: String,
18    missing: i64,
19}
20
21impl StatsAggregation {
22    pub fn new(name: &str) -> Self {
23        StatsAggregation {
24            name: name.to_string(),
25            ..Default::default()
26        }
27    }
28
29    pub fn set_field(mut self, field: &str) -> Self {
30        self.value.field = field.to_string();
31        self
32    }
33
34    pub fn set_script(mut self, script: &str) -> Self {
35        self.value.script = script.to_string();
36        self
37    }
38    pub fn set_missing(mut self, missing: i64) -> Self {
39        self.value.missing = missing;
40        self
41    }
42    pub fn set_aggregation<T>(mut self, aggregation: T) -> Self
43    where
44        T: AggregationTrait,
45    {
46        self.aggregation = aggregation.build();
47        self
48    }
49    pub fn append_aggregation<T>(mut self, query: T) -> Self
50    where
51        T: AggregationTrait,
52    {
53        let mut values = self.aggregation.clone();
54        merge(&mut values, &query.build());
55        self.aggregation = json!(values);
56        return self;
57    }
58}
59
60impl Serialize for SumValue {
61    fn serialize<S>(&self, serializer: S) -> Result<<S as Serializer>::Ok, <S as Serializer>::Error>
62    where
63        S: Serializer,
64    {
65        let mut state = serializer.serialize_struct("SumValue", 0)?;
66
67        if !self.field.is_empty() {
68            state.serialize_field("field", &self.field)?;
69        }
70        if self.missing != 0 {
71            state.serialize_field("missing", &self.missing)?;
72        }
73        state.end()
74    }
75}
76
77impl Serialize for StatsAggregation {
78    fn serialize<S>(&self, serializer: S) -> Result<<S as Serializer>::Ok, <S as Serializer>::Error>
79    where
80        S: Serializer,
81    {
82        let mut state = serializer.serialize_struct("StatsAggregation", 0)?;
83        state.serialize_field("stats", &self.value)?;
84        if !(self.aggregation.is_null() || self.aggregation.to_string().is_empty()) {
85            state.serialize_field("aggs", &self.aggregation)?;
86        }
87        state.end()
88    }
89}
90
91impl AggregationTrait for StatsAggregation {
92    fn name(&self) -> &str {
93        self.name.as_str()
94    }
95
96    fn build(&self) -> Value {
97        let name = self.name.to_string();
98        json!({ name: self })
99    }
100
101    fn query_name(&self) -> String {
102        "stats".to_string()
103    }
104}
105
106#[cfg(test)]
107mod tests {
108    use super::*;
109    use crate::aggregation::AggregationTrait;
110
111    #[test]
112    fn test_terms_aggregation() {
113        let agg = StatsAggregation::new("hoge").set_field("aa");
114
115        let json = agg.build();
116        println!("{}", json);
117        // assert_eq!(json["test"]["terms"]["field"], "test");
118        // assert_eq!(json["test"]["terms"]["size"], 1);
119    }
120}