Skip to content

Commit

Permalink
Support position time_series_metric on geo_point fields (#93946)
Browse files Browse the repository at this point in the history
Added position time_series_metric:

* start creating position time_series_metric
* Add yaml tests for queries and aggs
* Disallow multi-values for geo_point as ts-metric
* Limit running on older versions, some parts of the time-series syntax were not supported on all versions
* ScaledFloatFieldMapper does not support POSITION, We should only test it against COUNTER and GAUGE, since it only supports those two metric types
* Expand unit tests and allow parsing of dimension. We expand the tests to cover all cases tested in DoubleFieldMapperTests which also tests the behaviour of setting the dimension to true or false, so we enable parsing that for symmetry, but reject `true` as illegal for geo_point.
* Add unit tests for position metric multi-values
  • Loading branch information
craigtaverner committed Mar 1, 2023
1 parent 663e34f commit e7a2c44
Show file tree
Hide file tree
Showing 14 changed files with 654 additions and 27 deletions.
5 changes: 5 additions & 0 deletions docs/changelog/93946.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
pr: 93946
summary: Support position `time_series_metric` on `geo_point` fields
area: "TSDB"
type: enhancement
issues: []
Original file line number Diff line number Diff line change
Expand Up @@ -299,7 +299,7 @@ public void testMetricAndDocvalues() {
}

public void testTimeSeriesIndexDefault() throws Exception {
var randomMetricType = randomFrom(TimeSeriesParams.MetricType.values());
var randomMetricType = randomFrom(TimeSeriesParams.MetricType.scalar());
var indexSettings = getIndexSettingsBuilder().put(IndexSettings.MODE.getKey(), IndexMode.TIME_SERIES.getName())
.put(IndexMetadata.INDEX_ROUTING_PATH.getKey(), "dimension_field");
var mapperService = createMapperService(indexSettings.build(), fieldMapping(b -> {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,316 @@
---
setup:
- skip:
version: " - 8.7.99"
reason: position metric introduced in 8.8.0
- do:
indices.create:
index: locations
body:
settings:
index:
mode: time_series
routing_path: [ city, name ]
time_series:
start_time: 2023-01-01T00:00:00Z
end_time: 2024-01-01T00:00:00Z
mappings:
properties:
"@timestamp":
type: date
city:
type: keyword
time_series_dimension: true
name:
type: keyword
time_series_dimension: true
location:
type: geo_point
time_series_metric: position

- do:
bulk:
index: locations
refresh: true
body: |
{"index":{}}
{"@timestamp": "2023-01-01T12:00:00Z", "location": "POINT(4.912350 52.374081)", "city": "Amsterdam", "name": "NEMO Science Museum"}
{"index":{}}
{"@timestamp": "2023-01-02T12:00:00Z", "location": "POINT(4.901618 52.369219)", "city": "Amsterdam", "name": "Museum Het Rembrandthuis"}
{"index":{}}
{"@timestamp": "2023-01-03T12:00:00Z", "location": "POINT(4.914722 52.371667)", "city": "Amsterdam", "name": "Nederlands Scheepvaartmuseum"}
{"index":{}}
{"@timestamp": "2023-01-04T12:00:00Z", "location": "POINT(4.405200 51.222900)", "city": "Antwerp", "name": "Letterenhuis"}
{"index":{}}
{"@timestamp": "2023-01-05T12:00:00Z", "location": "POINT(2.336389 48.861111)", "city": "Paris", "name": "Musée du Louvre"}
{"index":{}}
{"@timestamp": "2023-01-06T12:00:00Z", "location": "POINT(2.327000 48.860000)", "city": "Paris", "name": "Musée dOrsay"}
- do:
indices.refresh: { }

---
multi-valued fields unsupported:
- skip:
version: " - 8.7.99"
reason: position metric introduced in 8.8.0
- do:
bulk:
index: locations
refresh: true
body: |
{"index" : {}}
{"@timestamp": "2023-01-01T12:00:00Z", "city": "Rock", "name": "On", "location": {"lat": 13.0, "lon" : 34.0} }
{"index" : {}}
{"@timestamp": "2023-01-01T12:00:00Z", "city": "Hey", "name": "There", "location": [{"lat": 13.0, "lon" : 34.0}] }
{"index" : {}}
{"@timestamp": "2023-01-01T12:00:00Z", "city": "Boo", "name": "Hoo", "location": [{"lat": 13.0, "lon" : 34.0}, {"lat": 14.0, "lon" : 35.0}] }
- match: { errors: true }
- match: { items.0.index.result: "created" }
- match: { items.1.index.result: "created" }
- match: { items.2.index.error.reason: "failed to parse" }
- match: { items.2.index.error.caused_by.reason: "field type for [location] does not accept more than single value" }

---
"avg aggregation on position field unsupported":
- skip:
version: " - 8.7.99"
reason: position metric introduced in 8.8.0
- do:
catch: /Field \[location\] of type \[geo_point\] is not supported for aggregation \[avg\]/
search:
index: locations
body:
aggs:
avg_location:
avg:
field: location

---
"geo_bounds on position field":
- skip:
version: " - 8.7.99"
reason: position metric introduced in 8.8.0
features: close_to

- do:
search:
index: locations
rest_total_hits_as_int: true
body:
aggregations:
view_port:
geo_bounds:
field: location
wrap_longitude: true
- match: { hits.total: 6 }
- close_to: { aggregations.view_port.bounds.top_left.lat: { value: 52.374081, error: 0.00001 } }
- close_to: { aggregations.view_port.bounds.top_left.lon: { value: 2.327000, error: 0.00001 } }
- close_to: { aggregations.view_port.bounds.bottom_right.lat: { value: 48.860000, error: 0.00001 } }
- close_to: { aggregations.view_port.bounds.bottom_right.lon: { value: 4.914722, error: 0.00001 } }

- do:
search:
rest_total_hits_as_int: true
body:
aggregations:
centroid:
geo_centroid:
field: location
- match: { hits.total: 6 }
- match: { aggregations.centroid.location.lat: 51.00982965203002 }
- match: { aggregations.centroid.location.lon: 3.9662131341174245 }
- match: { aggregations.centroid.count: 6 }


---
"geo bounding box query":
- skip:
version: " - 8.7.99"
reason: position metric introduced in 8.8.0
- do:
search:
index: locations
body:
query:
geo_bounding_box:
location:
top_left:
lat: 53
lon: 4
bottom_right:
lat: 50
lon: 5
- match: { hits.total.value: 4 }

---
"geo shape intersects query":
- skip:
version: " - 8.7.99"
reason: position metric introduced in 8.8.0
- do:
search:
index: locations
body:
query:
geo_shape:
location:
shape:
type: "envelope"
coordinates: [ [ 0, 50 ], [ 4, 45 ] ]
- match: { hits.total.value: 2 }

---
"geo shape within query":
- skip:
version: " - 8.7.99"
reason: position metric introduced in 8.8.0
- do:
search:
index: locations
body:
query:
geo_shape:
location:
shape:
type: "envelope"
coordinates: [ [ 0, 50 ], [ 4, 45 ] ]
relation: within
- match: { hits.total.value: 2 }

---
"geo shape disjoint query":
- skip:
version: " - 8.7.99"
reason: position metric introduced in 8.8.0
- do:
search:
index: locations
body:
query:
geo_shape:
location:
shape:
type: "envelope"
coordinates: [ [ 0, 50 ], [ 4, 45 ] ]
relation: disjoint
- match: { hits.total.value: 4 }

---
"geo shape contains query":
- skip:
version: " - 8.7.99"
reason: position metric introduced in 8.8.0
- do:
search:
index: locations
body:
query:
geo_shape:
location:
shape:
type: "envelope"
coordinates: [ [ 0, 50 ], [ 4, 45 ] ]
relation: contains
- match: { hits.total.value: 0 }

---
"geo distance query":
- skip:
version: " - 8.7.99"
reason: position metric introduced in 8.8.0
- do:
search:
index: locations
body:
query:
geo_distance:
distance: "100km"
location:
lat: 52
lon: 5
- match: { hits.total.value: 4 }

---
"bounds agg":
- skip:
version: " - 8.7.99"
reason: position metric introduced in 8.8.0
features: close_to

- do:
search:
index: locations
body:
aggs:
bounds:
geo_bounds:
field: "location"
wrap_longitude: false
- match: { hits.total.value: 6 }
- close_to: { aggregations.bounds.bounds.top_left.lat: { value: 52.374081, error: 0.00001 } }
- close_to: { aggregations.bounds.bounds.top_left.lon: { value: 2.327000, error: 0.00001 } }
- close_to: { aggregations.bounds.bounds.bottom_right.lat: { value: 48.860000, error: 0.00001 } }
- close_to: { aggregations.bounds.bounds.bottom_right.lon: { value: 4.914722, error: 0.00001 } }

---
"geo_distance sort":
- skip:
version: " - 8.7.99"
reason: position metric introduced in 8.8.0
features: close_to

- do:
search:
index: locations
body:
sort:
_geo_distance:
location:
lat: 52.0
lon: 5.0
- match: { hits.total.value: 6 }
- close_to: { hits.hits.0._source.location.lat: { value: 52.369219, error: 0.00001 } }
- close_to: { hits.hits.0._source.location.lon: { value: 4.901618, error: 0.00001 } }
- close_to: { hits.hits.1._source.location.lat: { value: 52.371667, error: 0.00001 } }
- close_to: { hits.hits.1._source.location.lon: { value: 4.914722, error: 0.00001 } }
- close_to: { hits.hits.2._source.location.lat: { value: 52.374081, error: 0.00001 } }
- close_to: { hits.hits.2._source.location.lon: { value: 4.912350, error: 0.00001 } }
- close_to: { hits.hits.3._source.location.lat: { value: 51.222900, error: 0.00001 } }
- close_to: { hits.hits.3._source.location.lon: { value: 4.405200, error: 0.00001 } }
- close_to: { hits.hits.4._source.location.lat: { value: 48.861111, error: 0.00001 } }
- close_to: { hits.hits.4._source.location.lon: { value: 2.336389, error: 0.00001 } }
- close_to: { hits.hits.5._source.location.lat: { value: 48.860000, error: 0.00001 } }
- close_to: { hits.hits.5._source.location.lon: { value: 2.327000, error: 0.00001 } }


---
"distance_feature query":
- skip:
version: " - 8.7.99"
reason: position metric introduced in 8.8.0
features: close_to

- do:
search:
index: locations
body:
query:
bool:
should:
distance_feature:
field: "location"
pivot: "100km"
origin: [ 5.0, 52.0 ]
- match: { hits.total.value: 6 }
- close_to: { hits.hits.0._source.location.lat: { value: 52.369219, error: 0.00001 } }
- close_to: { hits.hits.0._source.location.lon: { value: 4.901618, error: 0.00001 } }
- close_to: { hits.hits.1._source.location.lat: { value: 52.371667, error: 0.00001 } }
- close_to: { hits.hits.1._source.location.lon: { value: 4.914722, error: 0.00001 } }
- close_to: { hits.hits.2._source.location.lat: { value: 52.374081, error: 0.00001 } }
- close_to: { hits.hits.2._source.location.lon: { value: 4.912350, error: 0.00001 } }
- close_to: { hits.hits.3._source.location.lat: { value: 51.222900, error: 0.00001 } }
- close_to: { hits.hits.3._source.location.lon: { value: 4.405200, error: 0.00001 } }
- close_to: { hits.hits.4._source.location.lat: { value: 48.861111, error: 0.00001 } }
- close_to: { hits.hits.4._source.location.lon: { value: 2.336389, error: 0.00001 } }
- close_to: { hits.hits.5._source.location.lat: { value: 48.860000, error: 0.00001 } }
- close_to: { hits.hits.5._source.location.lon: { value: 2.327000, error: 0.00001 } }

0 comments on commit e7a2c44

Please sign in to comment.