elasticsearch_dsl/search/aggregations/metrics/
cardinality_aggregation.rs

1use crate::search::*;
2use crate::util::*;
3
4/// A `single-value` metrics aggregation that calculates an approximate count of distinct values.
5///
6/// <https://www.elastic.co/guide/en/elasticsearch/reference/current/search-aggregations-metrics-cardinality-aggregation.html>
7#[derive(Debug, Clone, Serialize, PartialEq)]
8pub struct CardinalityAggregation {
9    cardinality: CardinalityAggregationInner,
10}
11
12#[derive(Debug, Clone, Serialize, PartialEq)]
13struct CardinalityAggregationInner {
14    field: String,
15
16    #[serde(skip_serializing_if = "ShouldSkip::should_skip")]
17    precision_threshold: Option<u16>,
18
19    #[serde(skip_serializing_if = "ShouldSkip::should_skip")]
20    missing: Option<String>,
21}
22
23impl Aggregation {
24    /// Creates an instance of [`CardinalityAggregation`]
25    ///
26    /// - `field` - field to aggregate
27    pub fn cardinality<T>(field: T) -> CardinalityAggregation
28    where
29        T: ToString,
30    {
31        CardinalityAggregation {
32            cardinality: CardinalityAggregationInner {
33                field: field.to_string(),
34                precision_threshold: None,
35                missing: None,
36            },
37        }
38    }
39}
40
41impl CardinalityAggregation {
42    /// The `precision_threshold` options allows to trade memory for accuracy, and defines a unique count below
43    /// which counts are expected to be close to accurate. Above this value, counts might become a bit more fuzzy.
44    /// The maximum supported value is 40000, thresholds above this number will have the same effect as a threshold
45    /// of 40000. The default value is 3000
46    pub fn precision_threshold(mut self, precision_threshold: u16) -> Self {
47        self.cardinality.precision_threshold = Some(precision_threshold);
48        self
49    }
50
51    /// The `missing` parameter defines how documents that are missing a value should be treated. By default they will
52    /// be ignored but it is also possible to treat them as if they had a value.
53    pub fn missing<T>(mut self, missing: T) -> Self
54    where
55        T: ToString,
56    {
57        self.cardinality.missing = Some(missing.to_string());
58        self
59    }
60}
61
62#[cfg(test)]
63mod tests {
64    use super::*;
65
66    #[test]
67    fn serialization() {
68        assert_serialize_aggregation(
69            Aggregation::cardinality("test_field"),
70            json!({ "cardinality": { "field": "test_field" } }),
71        );
72
73        assert_serialize_aggregation(
74            Aggregation::cardinality("test_field")
75                .precision_threshold(100u16)
76                .missing("N/A"),
77            json!({
78                "cardinality": {
79                    "field": "test_field",
80                    "precision_threshold": 100,
81                    "missing": "N/A"
82                }
83            }),
84        );
85    }
86}