elasticsearch_dsl/search/queries/term_level/
regexp_query.rs

1use crate::search::*;
2use crate::util::*;
3use serde::Serialize;
4
5/// Returns documents that contain terms matching a
6/// [regular expression](https://en.wikipedia.org/wiki/Regular_expression).
7///
8/// A regular expression is a way to match patterns in data using placeholder characters, called
9/// operators. For a list of operators supported by the `regexp` query, see
10/// [Regular expression syntax](https://www.elastic.co/guide/en/elasticsearch/reference/current/regexp-syntax.html).
11///
12/// To create a regexp query:
13/// ```
14/// # use elasticsearch_dsl::queries::*;
15/// # use elasticsearch_dsl::queries::params::*;
16/// # let query =
17/// Query::regexp("test", "username");
18/// ```
19/// <https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-regexp-query.html>
20#[derive(Debug, Clone, PartialEq, Serialize)]
21#[serde(remote = "Self")]
22pub struct RegexpQuery {
23    #[serde(skip)]
24    field: String,
25
26    value: String,
27
28    #[serde(
29        skip_serializing_if = "ShouldSkip::should_skip",
30        serialize_with = "join_with_pipe"
31    )]
32    flags: Vec<RegexpFlag>,
33
34    #[serde(skip_serializing_if = "ShouldSkip::should_skip")]
35    case_insensitive: Option<bool>,
36
37    #[serde(skip_serializing_if = "ShouldSkip::should_skip")]
38    max_determinized_states: Option<u64>,
39
40    #[serde(skip_serializing_if = "ShouldSkip::should_skip")]
41    rewrite: Option<Rewrite>,
42
43    #[serde(skip_serializing_if = "ShouldSkip::should_skip")]
44    boost: Option<f32>,
45
46    #[serde(skip_serializing_if = "ShouldSkip::should_skip")]
47    _name: Option<String>,
48}
49
50impl Query {
51    /// Creates an instance of [`RegexpQuery`]
52    ///
53    /// - `field` - Field you wish to search.
54    /// - `value` - Regular expression for terms you wish to find in the provided field. For a list
55    ///   of supported operators, see
56    ///   [Regular expression syntax](https://www.elastic.co/guide/en/elasticsearch/reference/current/regexp-syntax.html). <br/>
57    ///
58    /// By default, regular expressions are limited to 1,000 characters. You can change this limit
59    /// using the
60    /// [`index.max_regex_length`](https://www.elastic.co/guide/en/elasticsearch/reference/current/index-modules.html#index-max-regex-length) setting.
61    pub fn regexp<S>(field: S, value: S) -> RegexpQuery
62    where
63        S: ToString,
64    {
65        RegexpQuery {
66            field: field.to_string(),
67            value: value.to_string(),
68            flags: vec![],
69            case_insensitive: None,
70            max_determinized_states: None,
71            rewrite: None,
72            boost: None,
73            _name: None,
74        }
75    }
76}
77
78impl RegexpQuery {
79    /// Enables optional operators for the regular expression. For valid values and more
80    /// information, see
81    /// [Regular expression syntax](https://www.elastic.co/guide/en/elasticsearch/reference/current/regexp-syntax.html#regexp-optional-operators).
82    pub fn flags<I>(mut self, flags: I) -> Self
83    where
84        I: IntoIterator<Item = RegexpFlag>,
85    {
86        self.flags.extend(flags);
87        self
88    }
89
90    /// Allows case insensitive matching of the regular expression value with the indexed field
91    /// values when set to `true`. Default is `false` which means the case sensitivity of matching
92    /// depends on the underlying field’s mapping.
93    pub fn case_insensitive(mut self, case_insensitive: bool) -> Self {
94        self.case_insensitive = Some(case_insensitive);
95        self
96    }
97
98    /// Maximum number of
99    /// [automaton states](https://en.wikipedia.org/wiki/Deterministic_finite_automaton)
100    /// required for the query. Default is 10000.
101    ///
102    /// Elasticsearch uses [Apache Lucene](https://lucene.apache.org/core/) internally to parse
103    /// regular expressions. Lucene converts each regular expression to a finite automaton
104    /// containing a number of determinized states.
105    ///
106    /// You can use this parameter to prevent that conversion from unintentionally consuming too
107    /// many resources. You may need to increase this limit to run complex regular expressions.
108    pub fn max_determinized_states(mut self, max_determinized_states: u64) -> Self {
109        self.max_determinized_states = Some(max_determinized_states);
110        self
111    }
112
113    /// Method used to rewrite the query. For valid values and more information, see the
114    /// [rewrite](Rewrite) parameter.
115    pub fn rewrite(mut self, rewrite: Rewrite) -> Self {
116        self.rewrite = Some(rewrite);
117        self
118    }
119
120    add_boost_and_name!();
121}
122
123impl ShouldSkip for RegexpQuery {
124    fn should_skip(&self) -> bool {
125        self.value.should_skip()
126    }
127}
128
129serialize_with_root_keyed!("regexp": RegexpQuery);
130
131#[cfg(test)]
132mod tests {
133    use super::*;
134
135    #[test]
136    fn serialization() {
137        assert_serialize_query(
138            Query::regexp("test", "regexp"),
139            json!({
140                "regexp": {
141                    "test": {
142                        "value": "regexp"
143                    }
144                }
145            }),
146        );
147
148        assert_serialize_query(
149            Query::regexp("test", "regexp")
150                .flags([RegexpFlag::Complement, RegexpFlag::Interval])
151                .case_insensitive(false)
152                .max_determinized_states(2)
153                .rewrite(Rewrite::ConstantScore)
154                .boost(2)
155                .name("test"),
156            json!({
157                "regexp": {
158                    "test": {
159                        "value": "regexp",
160                        "flags": "COMPLEMENT|INTERVAL",
161                        "case_insensitive": false,
162                        "max_determinized_states": 2,
163                        "rewrite": "constant_score",
164                        "boost": 2.0,
165                        "_name": "test"
166                    }
167                }
168            }),
169        );
170    }
171}