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