elasticsearch_dsl/search/queries/span/
span_not_query.rs

1use crate::util::*;
2use crate::{Query, SpanQuery};
3use serde::Serialize;
4
5/// Removes matches which overlap with another span query or which are within x tokens before
6/// (controlled by the parameter `pre`) or y tokens after (controlled by the parameter `post`)
7/// another SpanQuery. The span not query maps to Lucene `SpanNotQuery`.
8///
9/// The `include` and `exclude` clauses can be any span type query. The `include` clause is the
10/// span query whose matches are filtered, and the `exclude` clause is the span query whose matches
11/// must not overlap those returned.
12///
13/// <https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-span-not-query.html>
14#[derive(Debug, Clone, PartialEq, Serialize)]
15#[serde(remote = "Self")]
16pub struct SpanNotQuery {
17    #[serde(skip_serializing_if = "ShouldSkip::should_skip")]
18    dist: Option<i32>,
19
20    #[serde(skip_serializing_if = "ShouldSkip::should_skip")]
21    exclude: Vec<SpanQuery>,
22
23    #[serde(skip_serializing_if = "ShouldSkip::should_skip")]
24    include: Vec<SpanQuery>,
25
26    #[serde(skip_serializing_if = "ShouldSkip::should_skip")]
27    post: Option<i32>,
28
29    #[serde(skip_serializing_if = "ShouldSkip::should_skip")]
30    pre: Option<i32>,
31}
32
33impl Query {
34    /// Creates an instance of [`SpanNotQuery`]
35    pub fn span_not<T, U>(exclude: T, include: U) -> SpanNotQuery
36    where
37        T: IntoIterator,
38        T::Item: Into<SpanQuery>,
39        U: IntoIterator,
40        U::Item: Into<SpanQuery>,
41    {
42        SpanNotQuery {
43            exclude: exclude.into_iter().map(Into::into).collect(),
44            include: include.into_iter().map(Into::into).collect(),
45            dist: None,
46            post: None,
47            pre: None,
48        }
49    }
50}
51
52impl SpanNotQuery {
53    /// If set the amount of tokens from within the include span can’t have overlap with the
54    /// exclude span.
55    ///
56    /// Equivalent of setting both `pre` and `post`.
57    pub fn dist(mut self, dist: i32) -> Self {
58        self.dist = Some(dist);
59        self
60    }
61
62    /// If set the amount of tokens after the include span can’t have overlap with the exclude span.
63    ///
64    /// Defaults to 0.
65    pub fn post(mut self, post: i32) -> Self {
66        self.post = Some(post);
67        self
68    }
69
70    /// If set the amount of tokens before the include span can’t have overlap with the exclude
71    /// span.
72    ///
73    /// Defaults to 0.
74    pub fn pre(mut self, pre: i32) -> Self {
75        self.pre = Some(pre);
76        self
77    }
78}
79
80impl ShouldSkip for SpanNotQuery {}
81
82serialize_with_root!("span_not": SpanNotQuery);
83
84#[cfg(test)]
85mod tests {
86    use super::*;
87
88    #[test]
89    fn serialization() {
90        assert_serialize_query(
91            Query::span_not(
92                [Query::span_term("foo", 1234)],
93                [Query::span_term("bar", 4321)],
94            )
95            .dist(1234)
96            .post(4321)
97            .pre(5678),
98            json!({
99                "span_not": {
100                    "dist": 1234,
101                    "exclude": [
102                        {
103                            "span_term": {
104                                "foo": {
105                                    "value": 1234
106                                }
107                            }
108                        }
109                    ],
110                    "include": [
111                        {
112                            "span_term": {
113                                "bar": {
114                                    "value": 4321
115                                }
116                            }
117                        }
118                    ],
119                    "post": 4321,
120                    "pre": 5678
121                }
122            }),
123        );
124
125        assert_serialize_query(
126            Query::span_not(
127                [Query::span_term("foo", 1234)],
128                [Query::span_term("bar", 4321)],
129            )
130            .dist(1234)
131            .post(4321)
132            .pre(5678),
133            json!({
134                "span_not": {
135                    "dist": 1234,
136                    "exclude": [
137                        {
138                            "span_term": {
139                                "foo": {
140                                    "value": 1234
141                                }
142                            }
143                        }
144                    ],
145                    "include": [
146                        {
147                            "span_term": {
148                                "bar": {
149                                    "value": 4321
150                                }
151                            }
152                        }
153                    ],
154                    "post": 4321,
155                    "pre": 5678
156                }
157            }),
158        );
159    }
160}