Skip to main content

opensearch_dsl/search/queries/span/
mod.rs

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