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}