Geo: better handling of malformed geo_points (#35554)
Improves handling of malformed geo_points when `ignore_malformed` is set to true Closes #35419
This commit is contained in:
parent
900caa20ef
commit
663563f64b
|
@ -97,8 +97,18 @@ public final class GeoPoint implements ToXContentFragment {
|
|||
throw new ElasticsearchParseException("failed to parse [{}], expected 2 or 3 coordinates "
|
||||
+ "but found: [{}]", vals.length);
|
||||
}
|
||||
double lat = Double.parseDouble(vals[0].trim());
|
||||
double lon = Double.parseDouble(vals[1].trim());
|
||||
final double lat;
|
||||
final double lon;
|
||||
try {
|
||||
lat = Double.parseDouble(vals[0].trim());
|
||||
} catch (NumberFormatException ex) {
|
||||
throw new ElasticsearchParseException("latitude must be a number");
|
||||
}
|
||||
try {
|
||||
lon = Double.parseDouble(vals[1].trim());
|
||||
} catch (NumberFormatException ex) {
|
||||
throw new ElasticsearchParseException("longitude must be a number");
|
||||
}
|
||||
if (vals.length > 2) {
|
||||
GeoPoint.assertZValue(ignoreZValue, Double.parseDouble(vals[2].trim()));
|
||||
}
|
||||
|
|
|
@ -260,7 +260,11 @@ public class GeoPointFieldMapper extends FieldMapper implements ArrayValueMapper
|
|||
throw new IllegalArgumentException("illegal longitude value [" + point.lon() + "] for " + name());
|
||||
}
|
||||
} else {
|
||||
GeoUtils.normalizePoint(point);
|
||||
if (isNormalizable(point.lat()) && isNormalizable(point.lon())) {
|
||||
GeoUtils.normalizePoint(point);
|
||||
} else {
|
||||
throw new ElasticsearchParseException("cannot normalize the point - not a number");
|
||||
}
|
||||
}
|
||||
if (fieldType().indexOptions() != IndexOptions.NONE) {
|
||||
context.doc().add(new LatLonPoint(fieldType().name(), point.lat(), point.lon()));
|
||||
|
@ -386,4 +390,8 @@ public class GeoPointFieldMapper extends FieldMapper implements ArrayValueMapper
|
|||
public Explicit<Boolean> ignoreZValue() {
|
||||
return ignoreZValue;
|
||||
}
|
||||
|
||||
private boolean isNormalizable(double coord) {
|
||||
return Double.isNaN(coord) == false && Double.isInfinite(coord) == false;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -456,4 +456,72 @@ public class GeoPointFieldMapperTests extends ESSingleNodeTestCase {
|
|||
assertThat(ex.getRootCause().getMessage(), equalTo("unsupported symbol [.] in geohash [1234.333]"));
|
||||
}
|
||||
|
||||
|
||||
public void testInvalidGeopointValuesIgnored() throws Exception {
|
||||
String mapping = Strings.toString(XContentFactory.jsonBuilder().startObject().startObject("type")
|
||||
.startObject("properties")
|
||||
.startObject("location")
|
||||
.field("type", "geo_point")
|
||||
.field("ignore_malformed", "true")
|
||||
.endObject()
|
||||
.endObject().endObject().endObject());
|
||||
|
||||
DocumentMapper defaultMapper = createIndex("test").mapperService().documentMapperParser()
|
||||
.parse("type", new CompressedXContent(mapping));
|
||||
|
||||
assertThat(defaultMapper.parse(SourceToParse.source("test", "type", "1",
|
||||
BytesReference.bytes(XContentFactory.jsonBuilder()
|
||||
.startObject().field("location", "1234.333").endObject()
|
||||
), XContentType.JSON)).rootDoc().getField("location"), nullValue());
|
||||
|
||||
assertThat(defaultMapper.parse(SourceToParse.source("test", "type", "1",
|
||||
BytesReference.bytes(XContentFactory.jsonBuilder()
|
||||
.startObject().field("lat", "-").field("lon", 1.3).endObject()
|
||||
), XContentType.JSON)).rootDoc().getField("location"), nullValue());
|
||||
|
||||
assertThat(defaultMapper.parse(SourceToParse.source("test", "type", "1",
|
||||
BytesReference.bytes(XContentFactory.jsonBuilder()
|
||||
.startObject().field("lat", 1.3).field("lon", "-").endObject()
|
||||
), XContentType.JSON)).rootDoc().getField("location"), nullValue());
|
||||
|
||||
assertThat(defaultMapper.parse(SourceToParse.source("test", "type", "1",
|
||||
BytesReference.bytes(XContentFactory.jsonBuilder()
|
||||
.startObject().field("location", "-,1.3").endObject()
|
||||
), XContentType.JSON)).rootDoc().getField("location"), nullValue());
|
||||
|
||||
assertThat(defaultMapper.parse(SourceToParse.source("test", "type", "1",
|
||||
BytesReference.bytes(XContentFactory.jsonBuilder()
|
||||
.startObject().field("location", "1.3,-").endObject()
|
||||
), XContentType.JSON)).rootDoc().getField("location"), nullValue());
|
||||
|
||||
assertThat(defaultMapper.parse(SourceToParse.source("test", "type", "1",
|
||||
BytesReference.bytes(XContentFactory.jsonBuilder()
|
||||
.startObject().field("lat", "NaN").field("lon", "NaN").endObject()
|
||||
), XContentType.JSON)).rootDoc().getField("location"), nullValue());
|
||||
|
||||
assertThat(defaultMapper.parse(SourceToParse.source("test", "type", "1",
|
||||
BytesReference.bytes(XContentFactory.jsonBuilder()
|
||||
.startObject().field("lat", 12).field("lon", "NaN").endObject()
|
||||
), XContentType.JSON)).rootDoc().getField("location"), nullValue());
|
||||
|
||||
assertThat(defaultMapper.parse(SourceToParse.source("test", "type", "1",
|
||||
BytesReference.bytes(XContentFactory.jsonBuilder()
|
||||
.startObject().field("lat", "NaN").field("lon", 10).endObject()
|
||||
), XContentType.JSON)).rootDoc().getField("location"), nullValue());
|
||||
|
||||
assertThat(defaultMapper.parse(SourceToParse.source("test", "type", "1",
|
||||
BytesReference.bytes(XContentFactory.jsonBuilder()
|
||||
.startObject().field("location", "NaN,NaN").endObject()
|
||||
), XContentType.JSON)).rootDoc().getField("location"), nullValue());
|
||||
|
||||
assertThat(defaultMapper.parse(SourceToParse.source("test", "type", "1",
|
||||
BytesReference.bytes(XContentFactory.jsonBuilder()
|
||||
.startObject().field("location", "10,NaN").endObject()
|
||||
), XContentType.JSON)).rootDoc().getField("location"), nullValue());
|
||||
|
||||
assertThat(defaultMapper.parse(SourceToParse.source("test", "type", "1",
|
||||
BytesReference.bytes(XContentFactory.jsonBuilder()
|
||||
.startObject().field("location", "NaN,12").endObject()
|
||||
), XContentType.JSON)).rootDoc().getField("location"), nullValue());
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue