elasticsearch_dsl/search/sort/
field_sort.rs1use super::{NestedFieldSort, SortMode, SortOrder};
2use crate::util::ShouldSkip;
3use crate::Term;
4use serde::Serialize;
5
6#[derive(Debug, Clone, PartialEq, Serialize)]
10#[serde(remote = "Self")]
11pub struct FieldSort {
12 #[serde(skip)]
13 field: String,
14
15 #[serde(skip_serializing_if = "ShouldSkip::should_skip")]
16 order: Option<SortOrder>,
17
18 #[serde(skip_serializing_if = "ShouldSkip::should_skip")]
19 mode: Option<SortMode>,
20
21 #[serde(skip_serializing_if = "ShouldSkip::should_skip")]
22 unmapped_type: Option<String>,
23
24 #[serde(skip_serializing_if = "ShouldSkip::should_skip")]
25 format: Option<String>,
26
27 #[serde(skip_serializing_if = "ShouldSkip::should_skip")]
28 missing: Option<Term>,
29
30 #[serde(skip_serializing_if = "ShouldSkip::should_skip")]
31 nested: Option<NestedFieldSort>,
32}
33
34impl FieldSort {
35 pub fn new<T>(field: T) -> Self
37 where
38 T: ToString,
39 {
40 Self {
41 field: field.to_string(),
42 order: None,
43 mode: None,
44 unmapped_type: None,
45 format: None,
46 missing: None,
47 nested: None,
48 }
49 }
50
51 pub fn ascending<T>(field: T) -> Self
53 where
54 T: ToString,
55 {
56 Self::new(field).order(SortOrder::Asc)
57 }
58
59 pub fn descending<T>(field: T) -> Self
61 where
62 T: ToString,
63 {
64 Self::new(field).order(SortOrder::Desc)
65 }
66
67 pub fn order(mut self, order: SortOrder) -> Self {
71 self.order = Some(order);
72 self
73 }
74
75 pub fn mode(mut self, mode: SortMode) -> Self {
79 self.mode = Some(mode);
80 self
81 }
82
83 pub fn unmapped_type<T>(mut self, unmapped_type: T) -> Self
87 where
88 T: ToString,
89 {
90 self.unmapped_type = Some(unmapped_type.to_string());
91 self
92 }
93
94 pub fn format<T>(mut self, format: T) -> Self
98 where
99 T: ToString,
100 {
101 self.format = Some(format.to_string());
102 self
103 }
104
105 pub fn missing<T>(mut self, missing: T) -> Self
109 where
110 T: Serialize,
111 {
112 self.missing = Term::new(missing);
113 self
114 }
115
116 pub fn nested(mut self, nested: NestedFieldSort) -> Self {
120 self.nested = Some(nested);
121 self
122 }
123}
124
125impl IntoIterator for FieldSort {
126 type Item = Self;
127
128 type IntoIter = std::option::IntoIter<Self::Item>;
129
130 fn into_iter(self) -> Self::IntoIter {
131 Some(self).into_iter()
132 }
133}
134
135serialize_keyed!(FieldSort: field);
136
137#[cfg(test)]
138mod tests {
139 use super::*;
140 use crate::util::assert_serialize;
141 use crate::{Query, SortSpecialField};
142
143 #[test]
144 fn serialization() {
145 assert_serialize(FieldSort::new("test"), json!({"test": {}}));
146
147 assert_serialize(
148 FieldSort::new(SortSpecialField::Score),
149 json!({"_score": {}}),
150 );
151
152 assert_serialize(
153 FieldSort::ascending("field"),
154 json!({ "field": { "order": "asc" } }),
155 );
156
157 assert_serialize(
158 FieldSort::descending("field"),
159 json!({ "field": { "order": "desc" } }),
160 );
161
162 assert_serialize(
163 FieldSort::ascending("test")
164 .order(SortOrder::Asc)
165 .mode(SortMode::Max)
166 .unmapped_type("long")
167 .missing("miss"),
168 json!({
169 "test": {
170 "order": "asc",
171 "mode": "max",
172 "unmapped_type": "long",
173 "missing": "miss",
174 }
175 }),
176 );
177
178 assert_serialize(
179 FieldSort::ascending("offer.price")
180 .order(SortOrder::Asc)
181 .mode(SortMode::Avg)
182 .nested(NestedFieldSort::path("offer").filter(Query::term("offer.color", "blue"))),
183 json!({
184 "offer.price": {
185 "mode": "avg",
186 "order": "asc",
187 "nested": {
188 "path": "offer",
189 "filter": {
190 "term": {
191 "offer.color": {
192 "value": "blue"
193 }
194 }
195 }
196 }
197 }
198 }),
199 );
200 }
201}