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}