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}