Skip to main content

opensearch_dsl/search/queries/
mod.rs

1//! Allows constructing OpenSearch search query.
2//!
3//! OpenSearch provides a full Query DSL (Domain Specific Language) based on
4//! JSON to define queries. Think of the Query DSL as an AST (Abstract Syntax
5//! Tree) of queries, consisting of two types of clauses:
6//!
7//! **Leaf query clauses**
8//!
9//! Leaf query clauses look for a particular value in a particular field, such
10//! as the match, term or range queries. These queries can be used by
11//! themselves.
12//!
13//! **Compound query clauses**
14//!
15//! Compound query clauses wrap other leaf or compound queries and are used to
16//! combine multiple queries in a logical fashion (such as the bool or dis_max
17//! query), or to alter their behavior (such as the constant_score query).
18//!
19//! <https://www.elastic.co/guide/en/opensearch/reference/current/query-dsl.html>
20
21// Public modules
22pub mod params;
23
24pub mod compound;
25pub mod custom;
26pub mod full_text;
27pub mod geo;
28pub mod joining;
29pub mod shape;
30pub mod span;
31pub mod specialized;
32pub mod term_level;
33
34pub use self::compound::*;
35pub use self::custom::*;
36pub use self::full_text::*;
37pub use self::geo::*;
38pub use self::joining::*;
39pub use self::shape::*;
40pub use self::span::*;
41pub use self::specialized::*;
42pub use self::term_level::*;
43
44// Very special queries
45mod match_all_query;
46mod match_none_query;
47mod query_collection;
48
49pub use self::match_all_query::*;
50pub use self::match_none_query::*;
51pub use self::query_collection::*;
52
53use crate::util::*;
54
55macro_rules! query {
56    ($($variant:ident($query:ty)),+ $(,)?) => {
57        /// A container enum for supported OpenSearch query types
58        #[derive(Clone, PartialEq, Serialize, Deserialize)]
59        #[serde(untagged)]
60        #[allow(missing_docs)]
61        pub enum Query {
62            $(
63                $variant($query),
64            )*
65        }
66
67        impl IntoIterator for Query {
68            type Item = Self;
69            type IntoIter = std::option::IntoIter<Self::Item>;
70
71            fn into_iter(self) -> Self::IntoIter {
72                if self.should_skip() {
73                    None.into_iter()
74                } else {
75                    Some(self).into_iter()
76                }
77            }
78        }
79
80        impl ShouldSkip for Query {
81            fn should_skip(&self) -> bool {
82                match self {
83                    $(
84                        Self::$variant(q) => q.should_skip(),
85                    )+
86                }
87            }
88        }
89
90        impl std::fmt::Debug for Query {
91            fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
92                match self {
93                    $(
94                        Self::$variant(q) => q.fmt(f),
95                    )+
96                }
97            }
98        }
99
100        $(
101            impl From<$query> for Query {
102                fn from(q: $query) -> Self {
103                    Query::$variant(q)
104                }
105            }
106
107            impl PartialEq<$query> for Query {
108                fn eq(&self, other: &$query) -> bool {
109                    match self {
110                        Self::$variant(query) => query.eq(other),
111                        _ => false,
112                    }
113                }
114            }
115
116            impl PartialEq<Query> for $query {
117                fn eq(&self, other: &Query) -> bool {
118                    match other {
119                        Query::$variant(query) => self.eq(query),
120                        _ => false,
121                    }
122                }
123            }
124
125            impl From<$query> for Option<Query> {
126                fn from(q: $query) -> Self {
127                    if q.should_skip() {
128                        None
129                    } else {
130                        Some(Query::$variant(q))
131                    }
132                }
133            }
134
135            impl IntoIterator for $query {
136                type Item = $query;
137
138                type IntoIter = std::option::IntoIter<Self::Item>;
139
140                fn into_iter(self) -> Self::IntoIter {
141                    if self.should_skip() {
142                        None.into_iter()
143                    } else {
144                        Some(self).into_iter()
145                    }
146                }
147            }
148        )+
149    };
150}
151
152query!(
153    Bool(BoolQuery),
154    Prefix(PrefixQuery),
155    Regexp(RegexpQuery),
156    Wildcard(WildcardQuery),
157    TermsSet(TermsSetQuery),
158    Term(TermQuery),
159    Terms(TermsQuery),
160    TermsLookup(TermsLookupQuery),
161    Exists(ExistsQuery),
162    Range(RangeQuery),
163    Ids(IdsQuery),
164    ConstantScore(ConstantScoreQuery),
165    DistanceFeatureDate(DistanceFeatureQuery<chrono::DateTime<chrono::Utc>>),
166    DistanceFeatureGeo(DistanceFeatureQuery<crate::GeoLocation>),
167    Match(MatchQuery),
168    MatchBoolPrefix(MatchBoolPrefixQuery),
169    MatchPhrasePrefix(MatchPhrasePrefixQuery),
170    MatchAll(MatchAllQuery),
171    MatchNone(MatchNoneQuery),
172    MatchPhrase(MatchPhraseQuery),
173    MultiMatch(MultiMatchQuery),
174    Nested(NestedQuery),
175    Boosting(BoostingQuery),
176    DisMax(DisMaxQuery),
177    Pinned(PinnedQuery),
178    Percolate(PercolateQuery),
179    PercolateLookup(PercolateLookupQuery),
180    FunctionScore(FunctionScoreQuery),
181    RankFeature(RankFeatureQuery),
182    RankFeatureSaturation(RankFeatureSaturationQuery),
183    RankFeatureLogarithm(RankFeatureLogarithmQuery),
184    RankFeatureSigmoid(RankFeatureSigmoidQuery),
185    RankFeatureLinear(RankFeatureLinearQuery),
186    MoreLikeThis(MoreLikeThisQuery),
187    Fuzzy(FuzzyQuery),
188    GeoDistance(GeoDistanceQuery),
189    GeoBoundingBox(GeoBoundingBoxQuery),
190    GeoShapeLookup(GeoShapeLookupQuery),
191    GeoShape(GeoShapeQuery),
192    ShapeLookup(ShapeLookupQuery),
193    Shape(ShapeQuery),
194    Json(JsonQuery),
195    Wrapper(WrapperQuery),
196    Script(ScriptQuery),
197    ScriptScore(ScriptScoreQuery),
198    ParentId(ParentIdQuery),
199    HasParent(HasParentQuery),
200    HasChild(HasChildQuery),
201    SimpleQueryString(SimpleQueryStringQuery),
202    QueryString(QueryStringQuery),
203    CombinedFields(CombinedFieldsQuery),
204    SpanContaining(SpanContainingQuery),
205    SpanFieldMasking(SpanFieldMaskingQuery),
206    SpanFirst(SpanFirstQuery),
207    SpanMulti(SpanMultiQuery),
208    SpanNear(SpanNearQuery),
209    SpanNot(SpanNotQuery),
210    SpanOr(SpanOrQuery),
211    SpanTerm(SpanTermQuery),
212    SpanWithin(SpanWithinQuery),
213    Knn(KnnQuery),
214);
215
216impl Default for Query {
217    fn default() -> Self {
218        Query::MatchAll(MatchAllQuery::default())
219    }
220}
221
222#[cfg(test)]
223mod tests {
224    use super::*;
225
226    #[test]
227    fn partial_eq() {
228        assert_eq!(
229            Query::term("field", "value"),
230            Query::from(Query::term("field", "value"))
231        );
232        assert_eq!(
233            Query::from(Query::term("field", "value")),
234            Query::term("field", "value"),
235        );
236    }
237}