elasticsearch_dsl/search/queries/term_level/
terms_lookup_query.rs

1use crate::search::*;
2use crate::util::*;
3
4/// Terms lookup fetches the field values of an existing document.
5/// Elasticsearch then uses those values as search terms. This can be
6/// helpful when searching for a large set of terms.
7///
8/// Because terms lookup fetches values from a document, the
9/// [`_source`](https://www.elastic.co/guide/en/elasticsearch/reference/current/mapping-source-field.html)
10/// mapping field must be enabled to use terms lookup. The `_source`
11/// field is enabled by default.
12///
13/// > By default, Elasticsearch limits the `terms` query to a maximum of
14/// > 65,536 terms. This includes terms fetched using terms lookup. You can
15/// > change this limit using the
16/// > [`index.max_terms_count setting`](https://www.elastic.co/guide/en/elasticsearch/reference/current/index-modules.html#index-max-terms-count).
17///
18/// To create a terms lookup query:
19/// ```
20/// # use elasticsearch_dsl::queries::*;
21/// # use elasticsearch_dsl::queries::params::*;
22/// # let query =
23/// Query::terms_lookup("test", "index", "id", "path")
24///     .routing("routing")
25///     .boost(1.3)
26///     .name("lookup");
27/// ```
28/// <https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-terms-query.html>
29#[derive(Debug, Clone, PartialEq, Serialize)]
30#[serde(remote = "Self")]
31pub struct TermsLookupQuery {
32    #[serde(skip)]
33    field: String,
34
35    #[serde(skip)]
36    terms_lookup: TermsLookup,
37
38    #[serde(skip_serializing_if = "ShouldSkip::should_skip")]
39    boost: Option<f32>,
40
41    #[serde(skip_serializing_if = "ShouldSkip::should_skip")]
42    _name: Option<String>,
43}
44
45#[derive(Debug, Clone, PartialEq, Serialize)]
46struct TermsLookup {
47    index: String,
48    id: String,
49    path: String,
50    #[serde(skip_serializing_if = "ShouldSkip::should_skip")]
51    routing: Option<String>,
52}
53
54impl Query {
55    /// Creates an instance of [`TermsLookupQuery`]
56    ///
57    /// - `field` - Field you wish to search.
58    /// - `index` - Name of the index from which to fetch field values.
59    /// - `id` - [ID](https://www.elastic.co/guide/en/elasticsearch/reference/current/mapping-id-field.html)
60    ///   of the document from which to fetch field values.
61    /// - `path` - Name of the field from which to fetch field values. Elasticsearch uses
62    ///   these values as search terms for the query. If the field values
63    ///   include an array of nested inner objects, you can access those objects
64    ///   using dot notation syntax.
65    pub fn terms_lookup<S, T, U, V>(field: S, index: T, id: U, path: V) -> TermsLookupQuery
66    where
67        S: ToString,
68        T: ToString,
69        U: ToString,
70        V: ToString,
71    {
72        TermsLookupQuery {
73            field: field.to_string(),
74            terms_lookup: TermsLookup {
75                index: index.to_string(),
76                id: id.to_string(),
77                path: path.to_string(),
78                routing: None,
79            },
80            boost: None,
81            _name: None,
82        }
83    }
84}
85
86impl TermsLookupQuery {
87    add_boost_and_name!();
88}
89
90impl TermsLookupQuery {
91    /// Custom [routing value](https://www.elastic.co/guide/en/elasticsearch/reference/current/mapping-routing-field.html)
92    /// of the document from which to fetch term values. If a custom routing
93    /// value was provided when the document was indexed, this parameter is
94    /// required.
95    pub fn routing<S>(mut self, routing: S) -> Self
96    where
97        S: ToString,
98    {
99        self.terms_lookup.routing = Some(routing.to_string());
100        self
101    }
102}
103
104impl ShouldSkip for TermsLookupQuery {}
105
106serialize_with_root_key_value_pair!("terms": TermsLookupQuery, field, terms_lookup);
107
108#[cfg(test)]
109mod tests {
110    use super::*;
111
112    #[test]
113    fn serialization() {
114        assert_serialize_query(
115            Query::terms_lookup("test", "index_value", "id_value", "path_value"),
116            json!({
117                "terms": {
118                    "test": {
119                        "index": "index_value",
120                        "id": "id_value",
121                        "path": "path_value",
122                    }
123                }
124            }),
125        );
126
127        assert_serialize_query(
128            Query::terms_lookup("test", "index_value", "id_value", "path_value")
129                .routing("routing_value")
130                .boost(2)
131                .name("test"),
132            json!({
133                "terms": {
134                    "test": {
135                        "index": "index_value",
136                        "id": "id_value",
137                        "path": "path_value",
138                        "routing": "routing_value"
139                    },
140                    "boost": 2.0,
141                    "_name": "test",
142                }
143            }),
144        );
145    }
146}