1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
use crate::search::*;
use crate::util::*;
use serde::Serialize;

#[derive(Debug, Clone, Serialize, PartialEq)]
/// A single bucket aggregation that selects child documents that have the specified type,
/// then executes a sub-aggregation for the children documents.
///
/// <https://www.elastic.co/guide/en/elasticsearch/reference/current/search-aggregations-bucket-children-aggregation.html>
pub struct ChildrenAggregation {
    children: ChildrenAggregationInner,

    #[serde(skip_serializing_if = "ShouldSkip::should_skip")]
    aggs: Aggregations,
}

#[derive(Debug, Clone, Serialize, PartialEq)]
struct ChildrenAggregationInner {
    #[serde(rename = "type")]
    type_: String,
}

impl Aggregation {
    /// Creates an instance of [`ChildrenAggregation`]
    ///
    /// - `type_` - type of the child documents
    pub fn children<T>(type_: T) -> ChildrenAggregation
    where
        T: ToString,
    {
        ChildrenAggregation {
            children: ChildrenAggregationInner {
                type_: type_.to_string(),
            },
            aggs: Aggregations::new(),
        }
    }
}

impl ChildrenAggregation {
    add_aggregate!();
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn serialization() {
        assert_serialize_aggregation(
            Aggregation::children("answer"),
            json!({ "children": { "type": "answer" } }),
        );

        assert_serialize_aggregation(
            Aggregation::children("answer").aggregate("avg_score", Aggregation::avg("score")),
            json!({
                "children": {
                    "type": "answer"
                },
                "aggs": {
                    "avg_score": {
                        "avg": {
                            "field": "score"
                        }
                    }
                }
            }),
        );
    }
}