elasticsearch_dsl/search/collapse/
mod.rs

1//! Collapse search results
2//!
3//! <https://www.elastic.co/guide/en/elasticsearch/reference/current/collapse-search-results.html>
4
5use crate::util::*;
6use crate::*;
7
8/// Internal representation for collapse
9#[derive(Debug, Serialize, Clone, PartialEq)]
10pub struct Collapse {
11    field: String,
12
13    #[serde(skip_serializing_if = "ShouldSkip::should_skip")]
14    inner_hits: Vec<InnerHits>,
15
16    #[serde(skip_serializing_if = "ShouldSkip::should_skip")]
17    max_concurrent_group_searches: Option<u64>,
18}
19
20impl Collapse {
21    /// Creates an instance of [`Collapse`]
22    ///
23    /// - `field` - Field you wish to collapse on
24    pub fn new<T>(field: T) -> Self
25    where
26        T: ToString,
27    {
28        Self {
29            field: field.to_string(),
30            max_concurrent_group_searches: None,
31            inner_hits: Default::default(),
32        }
33    }
34
35    /// Add `inner_hits` to Collapse
36    pub fn inner_hits<T>(mut self, inner_hits: T) -> Self
37    where
38        T: IntoIterator,
39        T::Item: Into<InnerHits>,
40    {
41        self.inner_hits
42            .extend(inner_hits.into_iter().map(Into::into));
43        self
44    }
45
46    /// Add `max_concurrent_group_searches` to Collapse
47    pub fn max_concurrent_group_searches(mut self, max_concurrent_group_searches: u64) -> Self {
48        self.max_concurrent_group_searches = Some(max_concurrent_group_searches);
49        self
50    }
51}
52
53#[cfg(test)]
54mod tests {
55    use super::*;
56
57    #[test]
58    fn serialization() {
59        assert_serialize(Collapse::new("field"), json!({ "field": "field" }));
60
61        assert_serialize(
62            Collapse::new("field")
63                .max_concurrent_group_searches(10)
64                .inner_hits([InnerHits::new()
65                    .name("inner_hits")
66                    .size(10)
67                    .sort([FieldSort::descending("sort_field")])
68                    .collapse("field_inner_collapse")]),
69            json!({
70                "field": "field",
71                "inner_hits": [
72                    {
73                        "name": "inner_hits",
74                        "size": 10,
75                        "sort": [{"sort_field": {"order": "desc"}}],
76                        "collapse": {
77                            "field": "field_inner_collapse"
78                        }
79                    }
80                ],
81                "max_concurrent_group_searches": 10
82            }),
83        );
84
85        assert_serialize(
86            Collapse::new("field").inner_hits([
87                InnerHits::new()
88                    .name("inner_hits_0")
89                    .size(10)
90                    .sort([FieldSort::descending("sort_field")]),
91                InnerHits::new()
92                    .name("inner_hits_1")
93                    .size(10)
94                    .sort([FieldSort::descending("sort_field")]),
95            ]),
96            json!({
97                "field": "field",
98                "inner_hits": [
99                    {
100                        "name": "inner_hits_0",
101                        "size": 10,
102                        "sort": [{"sort_field": {"order": "desc"}}]
103                    },
104                    {
105                        "name": "inner_hits_1",
106                        "size": 10,
107                        "sort": [{"sort_field": {"order": "desc"}}]
108                    }
109                ]
110            }),
111        );
112    }
113}