elasticsearch_dsl/search/sort/
script_sort.rs

1use super::SortOrder;
2use crate::util::ShouldSkip;
3use crate::{Script, ScriptSortType};
4use serde::Serialize;
5
6/// Sorts search hits by script result
7///
8/// <https://www.elastic.co/guide/en/elasticsearch/reference/current/sort-search-results.html#script-based-sorting>
9#[derive(Debug, Clone, PartialEq, Eq, Serialize)]
10#[serde(remote = "Self")]
11pub struct ScriptSort {
12    script: Script,
13
14    #[serde(skip_serializing_if = "ShouldSkip::should_skip")]
15    order: Option<SortOrder>,
16
17    #[serde(skip_serializing_if = "ShouldSkip::should_skip")]
18    r#type: Option<ScriptSortType>,
19}
20
21impl ScriptSort {
22    /// Creates an instance of [ScriptSort]
23    pub fn new(script: Script) -> Self {
24        Self {
25            script,
26            order: None,
27            r#type: None,
28        }
29    }
30
31    /// Creates an instance of [ScriptSort] by ascending order
32    pub fn ascending(script: Script) -> Self {
33        Self::new(script).order(SortOrder::Asc)
34    }
35
36    /// Creates an instance of [ScriptSort] by descending order
37    pub fn descending(script: Script) -> Self {
38        Self::new(script).order(SortOrder::Desc)
39    }
40
41    /// Explicit order
42    ///
43    /// <https://www.elastic.co/guide/en/elasticsearch/reference/current/sort-search-results.html#_sort_order>
44    pub fn order(mut self, order: SortOrder) -> Self {
45        self.order = Some(order);
46        self
47    }
48
49    /// Sort type for script result
50    pub fn r#type(mut self, r#type: ScriptSortType) -> Self {
51        self.r#type = Some(r#type);
52        self
53    }
54}
55
56impl IntoIterator for ScriptSort {
57    type Item = Self;
58
59    type IntoIter = std::option::IntoIter<Self::Item>;
60
61    fn into_iter(self) -> Self::IntoIter {
62        Some(self).into_iter()
63    }
64}
65
66serialize_with_root!("_script": ScriptSort);
67
68#[cfg(test)]
69mod tests {
70    use super::*;
71    use crate::util::assert_serialize;
72
73    #[test]
74    fn serialization() {
75        assert_serialize(
76            ScriptSort::ascending(
77                Script::source("doc['numberOfCommits'].value * params.factor").param("factor", 1.1),
78            )
79            .r#type(ScriptSortType::Number),
80            json!({
81                "_script": {
82                    "order": "asc",
83                    "type": "number",
84                    "script": {
85                        "source": "doc['numberOfCommits'].value * params.factor",
86                        "params": {
87                            "factor": 1.1
88                        }
89                    }
90                }
91            }),
92        );
93    }
94}