elasticsearch_dsl/search/queries/span/
mod.rs

1//! Span queries are low-level positional queries which provide expert control over the order and
2//! proximity of the specified terms. These are typically used to implement very specific queries
3//! on legal documents or patents.
4//!
5//! It is only allowed to set boost on an outer span query. Compound span queries, like span_near,
6//! only use the list of matching spans of inner span queries in order to find their own spans,
7//! which they then use to produce a score. Scores are never computed on inner span queries, which
8//! is the reason why boosts are not allowed: they only influence the way scores are computed, not
9//! spans.
10//!
11//! Span queries cannot be mixed with non-span queries (with the exception of the span_multi query).
12
13mod span_containing_query;
14mod span_field_masking_query;
15mod span_first_query;
16mod span_multi_query;
17mod span_near_query;
18mod span_not_query;
19mod span_or_query;
20mod span_term_query;
21mod span_within_query;
22
23pub use self::span_containing_query::*;
24pub use self::span_field_masking_query::*;
25pub use self::span_first_query::*;
26pub use self::span_multi_query::*;
27pub use self::span_near_query::*;
28pub use self::span_not_query::*;
29pub use self::span_or_query::*;
30pub use self::span_term_query::*;
31pub use self::span_within_query::*;
32
33use crate::util::*;
34use crate::{FuzzyQuery, PrefixQuery, RangeQuery, RegexpQuery, WildcardQuery};
35
36macro_rules! span_query {
37    ($($variant:ident($query:ty)),+ $(,)?) => {
38        /// A container enum for supported Elasticsearch query types
39        #[derive(Clone, PartialEq, Serialize)]
40        #[serde(untagged)]
41        #[allow(missing_docs)]
42        pub enum SpanQuery {
43            $(
44                $variant($query),
45            )*
46        }
47
48        impl IntoIterator for SpanQuery {
49            type Item = Self;
50            type IntoIter = std::option::IntoIter<Self::Item>;
51
52            fn into_iter(self) -> Self::IntoIter {
53                if self.should_skip() {
54                    None.into_iter()
55                } else {
56                    Some(self).into_iter()
57                }
58            }
59        }
60
61        impl ShouldSkip for SpanQuery {
62            fn should_skip(&self) -> bool {
63                match self {
64                    $(
65                        Self::$variant(q) => q.should_skip(),
66                    )+
67                }
68            }
69        }
70
71        impl std::fmt::Debug for SpanQuery {
72            fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
73                match self {
74                    $(
75                        Self::$variant(q) => q.fmt(f),
76                    )+
77                }
78            }
79        }
80
81        $(
82            impl From<$query> for SpanQuery {
83                fn from(q: $query) -> Self {
84                    SpanQuery::$variant(q)
85                }
86            }
87
88            impl PartialEq<$query> for SpanQuery {
89                fn eq(&self, other: &$query) -> bool {
90                    match self {
91                        Self::$variant(query) => query.eq(other),
92                        _ => false,
93                    }
94                }
95            }
96
97            impl PartialEq<SpanQuery> for $query {
98                fn eq(&self, other: &SpanQuery) -> bool {
99                    match other {
100                        SpanQuery::$variant(query) => self.eq(query),
101                        _ => false,
102                    }
103                }
104            }
105
106            impl From<$query> for Option<SpanQuery> {
107                fn from(q: $query) -> Self {
108                    if q.should_skip() {
109                        None
110                    } else {
111                        Some(SpanQuery::$variant(q))
112                    }
113                }
114            }
115        )+
116    };
117}
118
119macro_rules! multi_term_query {
120    ($($variant:ident($query:ty)),+ $(,)?) => {
121        /// A container enum for supported Elasticsearch query types
122        #[derive(Clone, PartialEq, Serialize)]
123        #[serde(untagged)]
124        #[allow(missing_docs)]
125        pub enum MultiTermQuery {
126            $(
127                $variant($query),
128            )*
129        }
130
131        impl IntoIterator for MultiTermQuery {
132            type Item = Self;
133            type IntoIter = std::option::IntoIter<Self::Item>;
134
135            fn into_iter(self) -> Self::IntoIter {
136                if self.should_skip() {
137                    None.into_iter()
138                } else {
139                    Some(self).into_iter()
140                }
141            }
142        }
143
144        impl ShouldSkip for MultiTermQuery {
145            fn should_skip(&self) -> bool {
146                match self {
147                    $(
148                        Self::$variant(q) => q.should_skip(),
149                    )+
150                }
151            }
152        }
153
154        impl std::fmt::Debug for MultiTermQuery {
155            fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
156                match self {
157                    $(
158                        Self::$variant(q) => q.fmt(f),
159                    )+
160                }
161            }
162        }
163
164        $(
165            impl From<$query> for MultiTermQuery {
166                fn from(q: $query) -> Self {
167                    MultiTermQuery::$variant(q)
168                }
169            }
170
171            impl PartialEq<$query> for MultiTermQuery {
172                fn eq(&self, other: &$query) -> bool {
173                    match self {
174                        Self::$variant(query) => query.eq(other),
175                        _ => false,
176                    }
177                }
178            }
179
180            impl PartialEq<MultiTermQuery> for $query {
181                fn eq(&self, other: &MultiTermQuery) -> bool {
182                    match other {
183                        MultiTermQuery::$variant(query) => self.eq(query),
184                        _ => false,
185                    }
186                }
187            }
188
189            impl From<$query> for Option<MultiTermQuery> {
190                fn from(q: $query) -> Self {
191                    if q.should_skip() {
192                        None
193                    } else {
194                        Some(MultiTermQuery::$variant(q))
195                    }
196                }
197            }
198        )+
199    };
200}
201
202span_query!(
203    SpanContaining(SpanContainingQuery),
204    SpanFieldMasking(SpanFieldMaskingQuery),
205    SpanFirst(SpanFirstQuery),
206    SpanMulti(SpanMultiQuery),
207    SpanNear(SpanNearQuery),
208    SpanNot(SpanNotQuery),
209    SpanOr(SpanOrQuery),
210    SpanTerm(SpanTermQuery),
211    SpanWithin(SpanWithinQuery),
212);
213
214multi_term_query!(
215    Prefix(PrefixQuery),
216    Regexp(RegexpQuery),
217    Wildcard(WildcardQuery),
218    Range(RangeQuery),
219    Fuzzy(FuzzyQuery),
220);