elasticsearch_dsl/search/queries/term_level/
terms_query.rs

1use crate::search::*;
2use crate::util::*;
3
4/// Returns documents that contain one or more **exact** terms in a provided field.
5/// The terms query is the same as the term query, except you can search for multiple values.
6///
7/// To create a terms query with numeric values:
8/// ```
9/// # use elasticsearch_dsl::queries::*;
10/// # use elasticsearch_dsl::queries::params::*;
11/// # let query =
12/// Query::terms("test", vec![123]);
13/// ```
14/// To create a terms query with string values and optional fields:
15/// ```
16/// # use elasticsearch_dsl::queries::*;
17/// # use elasticsearch_dsl::queries::params::*;
18/// # let query =
19/// Query::terms("test", vec!["username"])
20///     .boost(2)
21///     .name("test");
22/// ```
23/// <https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-terms-query.html>
24#[derive(Debug, Clone, PartialEq, Serialize)]
25#[serde(remote = "Self")]
26pub struct TermsQuery {
27    #[serde(skip)]
28    field: String,
29
30    #[serde(skip)]
31    terms: Terms,
32
33    #[serde(skip_serializing_if = "ShouldSkip::should_skip")]
34    boost: Option<f32>,
35
36    #[serde(skip_serializing_if = "ShouldSkip::should_skip")]
37    _name: Option<String>,
38}
39
40impl Query {
41    /// Creates an instance of [`TermsQuery`]
42    ///
43    /// - `field` - Field you wish to search.
44    /// - `values` - An array of terms you wish to find in the provided field. To return a
45    ///   document, one or more terms must exactly match a field value,
46    ///   including whitespace and capitalization.<br/>
47    ///   By default, Elasticsearch limits the `terms` query to a maximum of
48    ///   65,536 terms. You can change this limit using the
49    ///   [`index.max_terms_count setting`](https://www.elastic.co/guide/en/elasticsearch/reference/current/index-modules.html#index-max-terms-count).<br/>
50    /// > To use the field values of an existing document as search terms,
51    /// > use the terms lookup parameters.
52    pub fn terms<S, I>(field: S, terms: I) -> TermsQuery
53    where
54        S: ToString,
55        I: Into<Terms>,
56    {
57        TermsQuery {
58            field: field.to_string(),
59            terms: terms.into(),
60            boost: None,
61            _name: None,
62        }
63    }
64}
65
66impl TermsQuery {
67    add_boost_and_name!();
68}
69
70impl ShouldSkip for TermsQuery {
71    fn should_skip(&self) -> bool {
72        self.terms.should_skip()
73    }
74}
75
76serialize_with_root_key_value_pair!("terms": TermsQuery, field, terms);
77
78#[cfg(test)]
79mod tests {
80    use super::*;
81
82    #[test]
83    fn serialization() {
84        assert_serialize_query(
85            Query::terms("test", [12, 13, 123]),
86            json!({"terms": { "test": [12, 13, 123] } }),
87        );
88
89        assert_serialize_query(
90            Query::terms("test", [123]).boost(2).name("test"),
91            json!({
92                "terms": {
93                    "test": [123],
94                    "boost": 2.0,
95                    "_name": "test",
96                }
97            }),
98        );
99    }
100
101    #[test]
102    fn should_skip_when_there_are_no_values() {
103        let values: Vec<i32> = Vec::new();
104        let query = Query::terms("test", values);
105
106        assert!(query.should_skip())
107    }
108
109    #[test]
110    fn should_not_skip_when_there_are_no_values() {
111        let query = Query::terms("test", [123]);
112
113        assert!(!query.should_skip())
114    }
115}