elasticsearch_dsl/search/aggregations/bucket/
geotile_grid_aggregation.rs

1use crate::search::*;
2use crate::util::*;
3
4#[derive(Debug, Clone, Serialize, PartialEq)]
5/// A multi-bucket aggregation that groups geo_point and geo_shape values into buckets that represent a grid.
6/// The resulting grid can be sparse and only contains cells that have matching data. Each cell corresponds to
7/// a map tile as used by many online map sites. Each cell is labeled using a "{zoom}/{x}/{y}" format, where
8/// zoom is equal to the user-specified precision.
9///
10/// <https://www.elastic.co/guide/en/elasticsearch/reference/current/search-aggregations-bucket-geotilegrid-aggregation.html>
11pub struct GeotileGridAggregation {
12    geotile_grid: GeotileGridAggregationInner,
13
14    #[serde(skip_serializing_if = "ShouldSkip::should_skip")]
15    aggs: Aggregations,
16}
17
18#[derive(Debug, Clone, Serialize, PartialEq)]
19struct GeotileGridAggregationInner {
20    field: String,
21
22    #[serde(skip_serializing_if = "ShouldSkip::should_skip")]
23    precision: Option<u8>,
24
25    #[serde(skip_serializing_if = "ShouldSkip::should_skip")]
26    bounds: Option<GeoBoundingBox>,
27
28    #[serde(skip_serializing_if = "ShouldSkip::should_skip")]
29    size: Option<u64>,
30
31    #[serde(skip_serializing_if = "ShouldSkip::should_skip")]
32    shard_size: Option<u64>,
33}
34
35impl Aggregation {
36    /// Creates an instance of [`GeotileGridAggregation`]
37    ///
38    /// - `field` - field to group by
39    pub fn geotile_grid<T>(field: T) -> GeotileGridAggregation
40    where
41        T: ToString,
42    {
43        GeotileGridAggregation {
44            geotile_grid: GeotileGridAggregationInner {
45                field: field.to_string(),
46                precision: None,
47                bounds: None,
48                size: None,
49                shard_size: None,
50            },
51            aggs: Aggregations::new(),
52        }
53    }
54}
55
56impl GeotileGridAggregation {
57    /// The `size` parameter can be set to define the maximum number of buckets to return.Defaults to 10,000.
58    /// When results are trimmed, buckets are prioritized based on the volume of documents they contain.
59    pub fn size(mut self, size: u64) -> Self {
60        self.geotile_grid.size = Some(size);
61        self
62    }
63
64    /// The `shard_size` parameter limits the number of buckets returned from each shard.
65    /// Defaults to max(10,(size x number-of-shards)) to allow for a more accurate count of
66    /// the top cells in the final result.Since each shard could have a different top result order,
67    /// using a larger number here reduces the risk of inaccurate counts, but incurs a performance cost.
68    pub fn shard_size(mut self, shard_size: u64) -> Self {
69        self.geotile_grid.shard_size = Some(shard_size);
70        self
71    }
72
73    /// the `precision` parameter is used to define cells/buckets in the results. Defaults to 7.
74    /// Values outside of \[0,29\] will be rejected.
75    pub fn precision(mut self, precision: u8) -> Self {
76        self.geotile_grid.precision = Some(precision);
77        self
78    }
79
80    /// the `bounds` parameter defines the bounding box used to filter the geo-points or geo-shapes in each bucket.
81    /// Accepts the same bounding box formats as the [`GeoBoundingBoxQuery`]
82    pub fn bounds<T>(mut self, bounds: T) -> Self
83    where
84        T: Into<GeoBoundingBox>,
85    {
86        self.geotile_grid.bounds = Some(bounds.into());
87        self
88    }
89
90    add_aggregate!();
91}
92
93#[cfg(test)]
94mod tests {
95    use super::*;
96
97    #[test]
98    fn serialization() {
99        assert_serialize_aggregation(
100            Aggregation::geotile_grid("test_field"),
101            json!({ "geotile_grid": { "field": "test_field" } }),
102        );
103
104        assert_serialize_aggregation(
105            Aggregation::geotile_grid("test_field")
106                .size(5)
107                .precision(18)
108                .shard_size(100)
109                .bounds(GeoBoundingBox::Vertices {
110                    top: 5.0,
111                    left: 52.4,
112                    bottom: 4.9,
113                    right: 52.3,
114                }),
115            json!({
116                "geotile_grid": {
117                    "field": "test_field",
118                    "size": 5,
119                    "precision": 18,
120                    "shard_size": 100,
121                    "bounds": {
122                        "top": 5.0,
123                        "left": 52.4,
124                        "bottom": 4.9,
125                        "right": 52.3,
126                    }
127                }
128            }),
129        );
130
131        assert_serialize_aggregation(
132            Aggregation::geotile_grid("test_field")
133                .size(0)
134                .precision(22)
135                .shard_size(16)
136                .bounds(GeoBoundingBox::Vertices {
137                    top: 25.0,
138                    left: 102.4,
139                    bottom: 7.9,
140                    right: 152.3,
141                })
142                .aggregate(
143                    "test_sub_agg",
144                    Aggregation::geotile_grid("test_field2")
145                        .size(2)
146                        .precision(12)
147                        .shard_size(22)
148                        .bounds(GeoBoundingBox::WellKnownText {
149                            wkt: "BBOX (-74.1, -71.12, 40.73, 40.01)".to_string(),
150                        }),
151                ),
152            json!({
153                "geotile_grid": {
154                    "field": "test_field",
155                    "size": 0,
156                    "precision": 22,
157                    "shard_size": 16,
158                    "bounds": {
159                        "top": 25.0,
160                        "left": 102.4,
161                        "bottom": 7.9,
162                        "right": 152.3,
163                    }
164                },
165                "aggs": {
166                    "test_sub_agg": {
167                        "geotile_grid": {
168                            "field": "test_field2",
169                            "size": 2,
170                            "precision": 12,
171                            "shard_size": 22,
172                            "bounds":{
173                                "wkt": "BBOX (-74.1, -71.12, 40.73, 40.01)"
174                            }
175                        }
176                    }
177                }
178            }),
179        );
180    }
181}