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}