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 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178
use crate::search::*;
use crate::util::*;
use serde::Serialize;
/// Queries documents that contain fields indexed using the `shape` type.
///
/// Requires the [`shape` Mapping](https://www.elastic.co/guide/en/elasticsearch/reference/current/shape.html).
///
/// <https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-shape-query.html>
#[derive(Debug, Clone, PartialEq, Serialize)]
#[serde(remote = "Self")]
pub struct ShapeLookupQuery {
#[serde(skip)]
field: String,
#[serde(skip)]
shape: Shape,
#[serde(skip_serializing_if = "ShouldSkip::should_skip")]
ignore_unmapped: Option<bool>,
#[serde(skip_serializing_if = "ShouldSkip::should_skip")]
boost: Option<f32>,
#[serde(skip_serializing_if = "ShouldSkip::should_skip")]
_name: Option<String>,
}
#[derive(Debug, Clone, PartialEq, Serialize)]
struct Shape {
indexed_shape: IndexedShape,
#[serde(skip_serializing_if = "ShouldSkip::should_skip")]
relation: Option<SpatialRelation>,
}
#[derive(Debug, Clone, PartialEq, Serialize)]
struct IndexedShape {
id: String,
#[serde(skip_serializing_if = "ShouldSkip::should_skip")]
index: Option<String>,
#[serde(skip_serializing_if = "ShouldSkip::should_skip")]
path: Option<String>,
#[serde(skip_serializing_if = "ShouldSkip::should_skip")]
routing: Option<String>,
}
impl Query {
/// Creates an instance of [`ShapeLookupQuery`]
///
/// - `field` - Field you wish to search
/// - `id` - The ID of the document that containing the pre-indexed shape
pub fn shape_lookup<S, T>(field: S, id: T) -> ShapeLookupQuery
where
S: ToString,
T: ToString,
{
ShapeLookupQuery {
field: field.to_string(),
shape: Shape {
indexed_shape: IndexedShape {
id: id.to_string(),
index: None,
path: None,
routing: None,
},
relation: None,
},
ignore_unmapped: None,
boost: None,
_name: None,
}
}
}
impl ShapeLookupQuery {
/// Name of the index where the pre-indexed shape is. Defaults to shapes
pub fn index<S>(mut self, index: S) -> Self
where
S: ToString,
{
self.shape.indexed_shape.index = Some(index.to_string());
self
}
/// The field specified as path containing the pre-indexed shape. Defaults to shape
pub fn path<S>(mut self, path: S) -> Self
where
S: ToString,
{
self.shape.indexed_shape.path = Some(path.to_string());
self
}
/// The routing of the shape document
pub fn routing<S>(mut self, routing: S) -> Self
where
S: ToString,
{
self.shape.indexed_shape.routing = Some(routing.to_string());
self
}
/// The [shape strategy](https://www.elastic.co/guide/en/elasticsearch/reference/current/geo-shape.html#spatial-strategy)
/// mapping parameter determines which spatial relation operators may be
/// used at search time.
pub fn relation(mut self, relation: SpatialRelation) -> Self {
self.shape.relation = Some(relation);
self
}
/// When set to true the `ignore_unmapped` option will ignore an unmapped
/// field and will not match any documents for this query. This can be
/// useful when querying multiple indexes which might have different
/// mappings. When set to `false` (the default value) the query will throw
/// an exception if the field is not mapped.
pub fn ignore_unmapped(mut self, ignore_unmapped: bool) -> Self {
self.ignore_unmapped = Some(ignore_unmapped);
self
}
add_boost_and_name!();
}
impl ShouldSkip for ShapeLookupQuery {}
serialize_with_root_key_value_pair!("shape": ShapeLookupQuery, field, shape);
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_serialization() {
assert_serialize_query(
Query::shape_lookup("pin.location", "id"),
json!({
"shape": {
"pin.location": {
"indexed_shape": {
"id": "id",
}
},
}
}),
);
assert_serialize_query(
Query::shape_lookup("pin.location", "id")
.boost(2)
.name("test")
.ignore_unmapped(true)
.relation(SpatialRelation::Within)
.routing("routing")
.index("index")
.path("path"),
json!({
"shape": {
"_name": "test",
"boost": 2.0,
"ignore_unmapped": true,
"pin.location": {
"indexed_shape": {
"id": "id",
"index": "index",
"path": "path",
"routing": "routing"
},
"relation": "WITHIN"
},
}
}),
);
}
}