[7.x][ML] Anomaly detection jobs should allow missing values for geo fields (#57300) (#57338)

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
This commit is contained in:
Dimitris Athanasiou 2020-05-29 13:06:16 +03:00 committed by GitHub
parent be6fa72432
commit 322f953060
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 46 additions and 2 deletions

View File

@ -24,9 +24,13 @@ public class GeoPointField extends DocValueField {
@Override @Override
public Object[] value(SearchHit hit) { public Object[] value(SearchHit hit) {
Object[] value = super.value(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)); throw new IllegalStateException("Unexpected values for a geo_point field: " + Arrays.toString(value));
} }
if (value[0] instanceof String) { if (value[0] instanceof String) {
value[0] = handleString((String) value[0]); value[0] = handleString((String) value[0]);
} else { } else {

View File

@ -36,9 +36,13 @@ public class GeoShapeField extends SourceField {
@Override @Override
public Object[] value(SearchHit hit) { public Object[] value(SearchHit hit) {
Object[] value = super.value(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)); throw new IllegalStateException("Unexpected values for a geo_shape field: " + Arrays.toString(value));
} }
if (value[0] instanceof String) { if (value[0] instanceof String) {
value[0] = handleString((String) value[0]); value[0] = handleString((String) value[0]);
} else if (value[0] instanceof Map<?, ?>) { } else if (value[0] instanceof Map<?, ?>) {

View File

@ -9,6 +9,8 @@ import org.elasticsearch.search.SearchHit;
import org.elasticsearch.test.ESTestCase; import org.elasticsearch.test.ESTestCase;
import org.elasticsearch.xpack.ml.test.SearchHitBuilder; import org.elasticsearch.xpack.ml.test.SearchHitBuilder;
import java.util.Arrays;
import static org.hamcrest.Matchers.contains; import static org.hamcrest.Matchers.contains;
import static org.hamcrest.Matchers.equalTo; import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.is; import static org.hamcrest.Matchers.is;
@ -36,4 +38,21 @@ public class GeoPointFieldTests extends ESTestCase {
assertThat(geo.isMultiField(), is(false)); assertThat(geo.isMultiField(), is(false));
expectThrows(UnsupportedOperationException.class, () -> geo.getParentField()); 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]"));
}
} }

View File

@ -59,4 +59,21 @@ public class GeoShapeFieldTests extends ESTestCase {
assertThat(geo.isMultiField(), is(false)); assertThat(geo.isMultiField(), is(false));
expectThrows(UnsupportedOperationException.class, () -> geo.getParentField()); 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]"));
}
} }