elasticsearch_dsl/search/
request.rs1use crate::search::*;
3use crate::util::*;
4use crate::Map;
5use crate::Set;
6
7#[derive(Debug, Default, Clone, Serialize, PartialEq)]
11pub struct Search {
12 #[serde(skip_serializing_if = "ShouldSkip::should_skip")]
13 runtime_mappings: Map<String, RuntimeMapping>,
14
15 #[serde(skip_serializing_if = "ShouldSkip::should_skip")]
16 indices_boost: Vec<KeyValuePair<String, f32>>,
17
18 #[serde(skip_serializing_if = "ShouldSkip::should_skip")]
19 min_score: Option<f32>,
20
21 #[serde(skip_serializing_if = "ShouldSkip::should_skip")]
22 _source: Option<SourceFilter>,
23
24 #[serde(skip_serializing_if = "ShouldSkip::should_skip")]
25 stats: Vec<String>,
26
27 #[serde(skip_serializing_if = "ShouldSkip::should_skip")]
28 from: Option<u64>,
29
30 #[serde(skip_serializing_if = "ShouldSkip::should_skip")]
31 size: Option<u64>,
32
33 #[serde(skip_serializing_if = "ShouldSkip::should_skip")]
34 query: Option<Query>,
35
36 #[serde(skip_serializing_if = "ShouldSkip::should_skip")]
37 sort: SortCollection,
38
39 #[serde(skip_serializing_if = "ShouldSkip::should_skip")]
40 aggs: Aggregations,
41
42 #[serde(skip_serializing_if = "ShouldSkip::should_skip")]
43 track_total_hits: Option<TrackTotalHits>,
44
45 #[serde(skip_serializing_if = "ShouldSkip::should_skip")]
46 highlight: Option<Highlight>,
47
48 #[serde(skip_serializing_if = "ShouldSkip::should_skip")]
49 rescore: RescoreCollection,
50
51 #[serde(skip_serializing_if = "ShouldSkip::should_skip")]
52 suggest: Map<String, Suggester>,
53
54 #[serde(skip_serializing_if = "ShouldSkip::should_skip")]
55 stored_fields: StoredFields,
56
57 #[serde(skip_serializing_if = "ShouldSkip::should_skip")]
58 docvalue_fields: Set<String>,
59
60 #[serde(skip_serializing_if = "ShouldSkip::should_skip")]
61 script_fields: Map<String, ScriptField>,
62
63 #[serde(skip_serializing_if = "ShouldSkip::should_skip")]
64 post_filter: Option<Query>,
65
66 #[serde(skip_serializing_if = "ShouldSkip::should_skip")]
67 pit: Option<PointInTime>,
68
69 #[serde(skip_serializing_if = "ShouldSkip::should_skip")]
70 search_after: Terms,
71
72 #[serde(skip_serializing_if = "ShouldSkip::should_skip")]
73 timeout: Option<Time>,
74
75 #[serde(skip_serializing_if = "ShouldSkip::should_skip")]
76 knn: Vec<Knn>,
77
78 #[serde(skip_serializing_if = "ShouldSkip::should_skip")]
79 collapse: Option<Collapse>,
80
81 #[serde(flatten)]
82 #[serde(skip_serializing_if = "ShouldSkip::should_skip")]
83 extra: Map<String, serde_json::Value>,
84
85 #[serde(skip_serializing_if = "ShouldSkip::should_skip")]
86 track_scores: Option<bool>,
87}
88
89impl Search {
90 pub fn new() -> Self {
92 Self::default()
93 }
94
95 pub fn runtime_mapping<S>(mut self, name: S, mapping: RuntimeMapping) -> Self
97 where
98 S: ToString,
99 {
100 let _ = self.runtime_mappings.insert(name.to_string(), mapping);
101 self
102 }
103
104 pub fn script_fields<S, T>(mut self, name: S, script: T) -> Self
106 where
107 S: ToString,
108 T: Into<ScriptField>,
109 {
110 let _ = self.script_fields.insert(name.to_string(), script.into());
111 self
112 }
113
114 pub fn indices_boost<T, U>(mut self, field: T, boost: U) -> Self
119 where
120 T: ToString,
121 U: num_traits::AsPrimitive<f32>,
122 {
123 self.indices_boost
124 .push(KeyValuePair::new(field.to_string(), boost.as_()));
125 self
126 }
127
128 pub fn min_score<F>(mut self, min_score: F) -> Self
134 where
135 F: Into<f32>,
136 {
137 self.min_score = Some(min_score.into());
138 self
139 }
140
141 pub fn source<S>(mut self, source: S) -> Self
143 where
144 S: Into<SourceFilter>,
145 {
146 self._source = Some(source.into());
147 self
148 }
149
150 pub fn stats<S>(mut self, stats: S) -> Self
152 where
153 S: ToString,
154 {
155 self.stats.push(stats.to_string());
156 self
157 }
158
159 pub fn from(mut self, from: u64) -> Self {
163 self.from = Some(from);
164 self
165 }
166
167 pub fn size(mut self, size: u64) -> Self {
171 self.size = Some(size);
172 self
173 }
174
175 pub fn query<Q>(mut self, query: Q) -> Self
178 where
179 Q: Into<Query>,
180 {
181 self.query = Some(query.into());
182 self
183 }
184
185 pub fn post_filter<Q>(mut self, post_filter: Q) -> Self
188 where
189 Q: Into<Query>,
190 {
191 self.post_filter = Some(post_filter.into());
192 self
193 }
194
195 pub fn sort<T>(mut self, sort: T) -> Self
197 where
198 T: IntoIterator,
199 T::Item: Into<Sort>,
200 {
201 self.sort.extend(sort);
202 self
203 }
204
205 pub fn track_total_hits<T>(mut self, track_total_hits: T) -> Self
207 where
208 T: Into<TrackTotalHits>,
209 {
210 self.track_total_hits = Some(track_total_hits.into());
211 self
212 }
213
214 pub fn track_scores(mut self, enabled: bool) -> Self {
216 self.track_scores = Some(enabled);
217 self
218 }
219
220 pub fn highlight<H>(mut self, highlight: H) -> Self
222 where
223 H: Into<Highlight>,
224 {
225 self.highlight = Some(highlight.into());
226 self
227 }
228
229 pub fn rescore<T>(mut self, rescore: T) -> Self
231 where
232 T: IntoIterator,
233 T::Item: Into<Rescore>,
234 {
235 self.rescore.extend(rescore);
236 self
237 }
238
239 pub fn suggest<T, U>(mut self, name: T, suggester: U) -> Self
241 where
242 T: ToString,
243 U: Into<Suggester>,
244 {
245 let _ = self.suggest.insert(name.to_string(), suggester.into());
246 self
247 }
248
249 pub fn stored_fields<T>(mut self, stored_fields: T) -> Self
251 where
252 T: Into<StoredFields>,
253 {
254 self.stored_fields = stored_fields.into();
255 self
256 }
257
258 pub fn docvalue_fields<T>(mut self, docvalue_fields: T) -> Self
260 where
261 T: IntoIterator,
262 T::Item: ToString,
263 {
264 self.docvalue_fields
265 .extend(docvalue_fields.into_iter().map(|x| x.to_string()));
266 self
267 }
268
269 pub fn pit(mut self, pit: PointInTime) -> Self {
271 self.pit = Some(pit);
272 self
273 }
274
275 pub fn search_after<T>(mut self, sort_values: T) -> Self
277 where
278 T: Into<Terms>,
279 {
280 self.search_after = sort_values.into();
281 self
282 }
283
284 pub fn timeout<T>(mut self, timeout: T) -> Self
288 where
289 T: Into<Time>,
290 {
291 self.timeout = Some(timeout.into());
292 self
293 }
294
295 pub fn knn(mut self, knn: Knn) -> Self {
299 self.knn.push(knn);
300 self
301 }
302
303 pub fn collapse<C>(mut self, collapse: C) -> Self
307 where
308 C: Into<Collapse>,
309 {
310 self.collapse = Some(collapse.into());
311 self
312 }
313
314 pub fn extra(mut self, extra: Map<String, serde_json::Value>) -> Self {
334 self.extra = extra;
335 self
336 }
337
338 add_aggregate!();
339}
340
341#[cfg(test)]
342mod tests {
343 use super::*;
344
345 #[test]
346 fn serializes_to_empty_object_by_default() {
347 assert_serialize(Search::new(), json!({}));
348 assert_serialize(Search::default(), json!({}));
349 }
350
351 #[test]
352 fn serializes_extra_fields() {
353 assert_serialize(
354 Search::new().size(10).track_scores(false).extra(
355 [
356 ("knn".to_owned(), json!({ "field": "abc" })),
357 ("terminate_after".to_owned(), json!(42)),
358 ]
359 .into(),
360 ),
361 json!({
362 "size": 10,
363 "track_scores": false,
364 "knn": { "field": "abc" },
365 "terminate_after": 42,
366 }),
367 );
368 }
369}