elasticsearch_dsl/search/queries/span/
span_near_query.rs

1use crate::util::*;
2use crate::Query;
3use crate::SpanQuery;
4use serde::Serialize;
5
6/// Matches spans which are near one another. One can specify _slop_, the maximum number of
7/// intervening unmatched positions, as well as whether matches are required to be in-order. The
8/// span near query maps to Lucene `SpanNearQuery`. <br/>
9/// The `clauses` element is a list of one or more other span type queries and the `slop` controls
10/// the maximum number of intervening unmatched positions permitted.
11///
12/// <https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-span-near-query.html>
13#[derive(Debug, Clone, PartialEq, Serialize)]
14#[serde(remote = "Self")]
15pub struct SpanNearQuery {
16    clauses: Vec<SpanQuery>,
17
18    #[serde(skip_serializing_if = "ShouldSkip::should_skip")]
19    in_order: Option<bool>,
20
21    #[serde(skip_serializing_if = "ShouldSkip::should_skip")]
22    slop: Option<i32>,
23}
24
25impl ShouldSkip for SpanNearQuery {
26    fn should_skip(&self) -> bool {
27        self.clauses.should_skip()
28    }
29}
30
31impl Query {
32    /// Creates an instance of [`SpanNearQuery`]
33    pub fn span_near<T>(clauses: T) -> SpanNearQuery
34    where
35        T: IntoIterator,
36        T::Item: Into<SpanQuery>,
37    {
38        SpanNearQuery {
39            clauses: clauses.into_iter().map(Into::into).collect(),
40            in_order: None,
41            slop: None,
42        }
43    }
44}
45
46impl SpanNearQuery {
47    /// Controls whether span matches are required to be in-order.
48    pub fn in_order(mut self, in_order: bool) -> Self {
49        self.in_order = Some(in_order);
50        self
51    }
52
53    /// The slop parameter allows you to specify the number of positions by which the terms in the query can be
54    /// transposed to match a document. A slop value of 0 (default) means that the terms must appear in the exact
55    /// order specified in the query.
56    pub fn slop(mut self, slop: i32) -> Self {
57        self.slop = Some(slop);
58        self
59    }
60}
61
62serialize_with_root!("span_near": SpanNearQuery);
63
64#[cfg(test)]
65mod tests {
66    use super::*;
67
68    #[test]
69    fn serialization() {
70        assert_serialize_query(
71            Query::span_near([Query::span_term("test", 1234)]),
72            json!({
73                "span_near": {
74                    "clauses": [
75                        {
76                            "span_term": {
77                                "test": {
78                                    "value": 1234
79                                }
80                            }
81                        }
82                    ]
83                }
84            }),
85        );
86
87        assert_serialize_query(
88            Query::span_near([Query::span_term("test", 1234)])
89                .in_order(true)
90                .slop(4321),
91            json!({
92                "span_near": {
93                    "clauses": [
94                        {
95                            "span_term": {
96                                "test": {
97                                    "value": 1234
98                                }
99                            }
100                        }
101                    ],
102                    "in_order": true,
103                    "slop": 4321
104                }
105            }),
106        );
107    }
108}