From c6558986c427a01937cd179ea8646d2abd6cc92b Mon Sep 17 00:00:00 2001 From: Dimitris Athanasiou Date: Fri, 29 May 2020 11:28:40 +0300 Subject: [PATCH] [7.7][ML] Anomaly detection jobs should allow missing values for geo fields (#57300) Allows geo fields (`geo_point`, `geo_shape`) to have missing values. Fixes a bug where such missing values would result in an error. Closes #57299 Backport of #57300 --- .../xpack/ml/extractor/GeoPointField.java | 6 +++++- .../xpack/ml/extractor/GeoShapeField.java | 6 +++++- .../ml/extractor/GeoPointFieldTests.java | 19 +++++++++++++++++++ .../ml/extractor/GeoShapeFieldTests.java | 17 +++++++++++++++++ 4 files changed, 46 insertions(+), 2 deletions(-) diff --git a/x-pack/plugin/ml/src/main/java/org/elasticsearch/xpack/ml/extractor/GeoPointField.java b/x-pack/plugin/ml/src/main/java/org/elasticsearch/xpack/ml/extractor/GeoPointField.java index e39ac7859c2c3..80070e3876b1a 100644 --- a/x-pack/plugin/ml/src/main/java/org/elasticsearch/xpack/ml/extractor/GeoPointField.java +++ b/x-pack/plugin/ml/src/main/java/org/elasticsearch/xpack/ml/extractor/GeoPointField.java @@ -24,9 +24,13 @@ public GeoPointField(String name) { @Override public Object[] value(SearchHit hit) { Object[] value = super.value(hit); - if (value.length != 1) { + if (value.length == 0) { + return value; + } + if (value.length > 1) { throw new IllegalStateException("Unexpected values for a geo_point field: " + Arrays.toString(value)); } + if (value[0] instanceof String) { value[0] = handleString((String) value[0]); } else { diff --git a/x-pack/plugin/ml/src/main/java/org/elasticsearch/xpack/ml/extractor/GeoShapeField.java b/x-pack/plugin/ml/src/main/java/org/elasticsearch/xpack/ml/extractor/GeoShapeField.java index 5ff58712f6e78..3bce9b408326e 100644 --- a/x-pack/plugin/ml/src/main/java/org/elasticsearch/xpack/ml/extractor/GeoShapeField.java +++ b/x-pack/plugin/ml/src/main/java/org/elasticsearch/xpack/ml/extractor/GeoShapeField.java @@ -36,9 +36,13 @@ public GeoShapeField(String name) { @Override public Object[] value(SearchHit hit) { Object[] value = super.value(hit); - if (value.length != 1) { + if (value.length == 0) { + return value; + } + if (value.length > 1) { throw new IllegalStateException("Unexpected values for a geo_shape field: " + Arrays.toString(value)); } + if (value[0] instanceof String) { value[0] = handleString((String) value[0]); } else if (value[0] instanceof Map) { diff --git a/x-pack/plugin/ml/src/test/java/org/elasticsearch/xpack/ml/extractor/GeoPointFieldTests.java b/x-pack/plugin/ml/src/test/java/org/elasticsearch/xpack/ml/extractor/GeoPointFieldTests.java index bd9b00254930d..cab6fe758b002 100644 --- a/x-pack/plugin/ml/src/test/java/org/elasticsearch/xpack/ml/extractor/GeoPointFieldTests.java +++ b/x-pack/plugin/ml/src/test/java/org/elasticsearch/xpack/ml/extractor/GeoPointFieldTests.java @@ -9,6 +9,8 @@ import org.elasticsearch.test.ESTestCase; import org.elasticsearch.xpack.ml.test.SearchHitBuilder; +import java.util.Arrays; + import static org.hamcrest.Matchers.contains; import static org.hamcrest.Matchers.equalTo; import static org.hamcrest.Matchers.is; @@ -36,4 +38,21 @@ public void testGivenGeoPoint() { assertThat(geo.isMultiField(), is(false)); expectThrows(UnsupportedOperationException.class, () -> geo.getParentField()); } + + public void testMissing() { + SearchHit hit = new SearchHitBuilder(42).addField("a_keyword", "bar").build(); + + ExtractedField geo = new GeoPointField("missing"); + + assertThat(geo.value(hit), equalTo(new Object[0])); + } + + public void testArray() { + SearchHit hit = new SearchHitBuilder(42).addField("geo", Arrays.asList(1, 2)).build(); + + ExtractedField geo = new GeoPointField("geo"); + + IllegalStateException e = expectThrows(IllegalStateException.class, () -> geo.value(hit)); + assertThat(e.getMessage(), equalTo("Unexpected values for a geo_point field: [1, 2]")); + } } diff --git a/x-pack/plugin/ml/src/test/java/org/elasticsearch/xpack/ml/extractor/GeoShapeFieldTests.java b/x-pack/plugin/ml/src/test/java/org/elasticsearch/xpack/ml/extractor/GeoShapeFieldTests.java index 79ac9849375cc..4af08a7253d0f 100644 --- a/x-pack/plugin/ml/src/test/java/org/elasticsearch/xpack/ml/extractor/GeoShapeFieldTests.java +++ b/x-pack/plugin/ml/src/test/java/org/elasticsearch/xpack/ml/extractor/GeoShapeFieldTests.java @@ -59,4 +59,21 @@ public void testWKTFormat() { assertThat(geo.isMultiField(), is(false)); expectThrows(UnsupportedOperationException.class, () -> geo.getParentField()); } + + public void testMissing() { + SearchHit hit = new SearchHitBuilder(42).addField("a_keyword", "bar").build(); + + ExtractedField geo = new GeoShapeField("missing"); + + assertThat(geo.value(hit), equalTo(new Object[0])); + } + + public void testArray() { + SearchHit hit = new SearchHitBuilder(42).setSource("{\"geo\":[1,2]}").build(); + + ExtractedField geo = new GeoShapeField("geo"); + + IllegalStateException e = expectThrows(IllegalStateException.class, () -> geo.value(hit)); + assertThat(e.getMessage(), equalTo("Unexpected values for a geo_shape field: [1, 2]")); + } }