elasticsearch_dsl/search/queries/
mod.rs

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