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