diff --git a/core/src/main/java/org/elasticsearch/index/query/GeoBoundingBoxQueryBuilder.java b/core/src/main/java/org/elasticsearch/index/query/GeoBoundingBoxQueryBuilder.java index c7269925da7..4ad63ebc1fc 100644 --- a/core/src/main/java/org/elasticsearch/index/query/GeoBoundingBoxQueryBuilder.java +++ b/core/src/main/java/org/elasticsearch/index/query/GeoBoundingBoxQueryBuilder.java @@ -22,7 +22,6 @@ package org.elasticsearch.index.query; import org.apache.lucene.search.Query; import org.elasticsearch.Version; import org.elasticsearch.common.Numbers; -import org.elasticsearch.common.Strings; import org.elasticsearch.common.geo.GeoPoint; import org.elasticsearch.common.geo.GeoUtils; import org.elasticsearch.common.io.stream.StreamInput; @@ -47,10 +46,6 @@ import java.util.Objects; public class GeoBoundingBoxQueryBuilder extends AbstractQueryBuilder { /** Name of the query. */ public static final String NAME = "geo_bbox"; - /** Default for geo point coerce (as of this writing false). */ - public static final boolean DEFAULT_COERCE = false; - /** Default for skipping geo point validation (as of this writing false). */ - public static final boolean DEFAULT_IGNORE_MALFORMED = false; /** Default type for executing this query (memory as of this writing). */ public static final GeoExecType DEFAULT_TYPE = GeoExecType.MEMORY; /** Needed for serialization. */ @@ -62,10 +57,8 @@ public class GeoBoundingBoxQueryBuilder extends AbstractQueryBuilder field : { lat : 30, lon : 12 } String currentName = parser.currentName(); + assert currentFieldName != null; fieldName = currentFieldName; while ((token = parser.nextToken()) != XContentParser.Token.END_OBJECT) { if (token == XContentParser.Token.FIELD_NAME) { @@ -125,6 +127,8 @@ public class GeoDistanceQueryParser implements QueryParser shell; - private boolean coerce = false; - - private boolean ignoreMalformed = false; + private GeoValidationMethod validationMethod = GeoValidationMethod.DEFAULT; public GeoPolygonQueryBuilder(String fieldName, List points) { if (Strings.isEmpty(fieldName)) { @@ -85,27 +83,15 @@ public class GeoPolygonQueryBuilder extends AbstractQueryBuilder shell = null; Float boost = null; - Boolean coerce = null; - Boolean ignoreMalformed = null; + boolean coerce = GeoValidationMethod.DEFAULT_LENIENT_PARSING; + boolean ignoreMalformed = GeoValidationMethod.DEFAULT_LENIENT_PARSING; + GeoValidationMethod validationMethod = null; String queryName = null; String currentFieldName = null; XContentParser.Token token; @@ -106,6 +108,8 @@ public class GeoPolygonQueryParser implements QueryParser{ + COERCE, IGNORE_MALFORMED, STRICT; + + public static final GeoValidationMethod DEFAULT = STRICT; + public static final boolean DEFAULT_LENIENT_PARSING = (DEFAULT != STRICT); + private static final GeoValidationMethod PROTOTYPE = DEFAULT; + + @Override + public GeoValidationMethod readFrom(StreamInput in) throws IOException { + return GeoValidationMethod.values()[in.readVInt()]; + } + + public static GeoValidationMethod readGeoValidationMethodFrom(StreamInput in) throws IOException { + return PROTOTYPE.readFrom(in); + } + + @Override + public void writeTo(StreamOutput out) throws IOException { + out.writeVInt(this.ordinal()); + } + + public static GeoValidationMethod fromString(String op) { + for (GeoValidationMethod method : GeoValidationMethod.values()) { + if (method.name().equalsIgnoreCase(op)) { + return method; + } + } + throw new IllegalArgumentException("operator needs to be either " + CollectionUtils.arrayAsArrayList(GeoValidationMethod.values()) + + ", but not [" + op + "]"); + } + + /** Returns whether or not to skip bounding box validation. */ + public static boolean isIgnoreMalformed(GeoValidationMethod method) { + return (method == GeoValidationMethod.IGNORE_MALFORMED || method == GeoValidationMethod.COERCE); + } + + /** Returns whether or not to try and fix broken/wrapping bounding boxes. */ + public static boolean isCoerce(GeoValidationMethod method) { + return method == GeoValidationMethod.COERCE; + } + + /** Returns validation method corresponding to given coerce and ignoreMalformed values. */ + public static GeoValidationMethod infer(boolean coerce, boolean ignoreMalformed) { + if (coerce) { + return GeoValidationMethod.COERCE; + } else if (ignoreMalformed) { + return GeoValidationMethod.IGNORE_MALFORMED; + } else { + return GeoValidationMethod.STRICT; + } + } + +} diff --git a/core/src/test/java/org/elasticsearch/index/query/GeoBoundingBoxQueryBuilderTests.java b/core/src/test/java/org/elasticsearch/index/query/GeoBoundingBoxQueryBuilderTests.java index e94bc332a22..c138ad0e310 100644 --- a/core/src/test/java/org/elasticsearch/index/query/GeoBoundingBoxQueryBuilderTests.java +++ b/core/src/test/java/org/elasticsearch/index/query/GeoBoundingBoxQueryBuilderTests.java @@ -73,10 +73,7 @@ public class GeoBoundingBoxQueryBuilderTests extends AbstractQueryTestCase polygon = randomPolygon(randomIntBetween(4, 50)); GeoPolygonQueryBuilder builder = new GeoPolygonQueryBuilder(GEO_POINT_FIELD_NAME, polygon); - builder.coerce(randomBoolean()); - builder.ignoreMalformed(randomBoolean()); + if (randomBoolean()) { + builder.setValidationMethod(randomFrom(GeoValidationMethod.values())); + } return builder; } @@ -62,7 +63,7 @@ public class GeoPolygonQueryBuilderTests extends AbstractQueryTestCase queryBuilderPoints = queryBuilder.points(); GeoPoint[] queryPoints = geoQuery.points(); assertThat(queryPoints.length, equalTo(queryBuilderPoints.size())); - if (queryBuilder.coerce()) { + if (GeoValidationMethod.isCoerce(queryBuilder.getValidationMethod())) { for (int i = 0; i < queryBuilderPoints.size(); i++) { GeoPoint queryBuilderPoint = queryBuilderPoints.get(i); GeoUtils.normalizePoint(queryBuilderPoint, true, true); diff --git a/core/src/test/java/org/elasticsearch/search/geo/GeoBoundingBoxIT.java b/core/src/test/java/org/elasticsearch/search/geo/GeoBoundingBoxIT.java index 1f4e953e25e..b61b38993ee 100644 --- a/core/src/test/java/org/elasticsearch/search/geo/GeoBoundingBoxIT.java +++ b/core/src/test/java/org/elasticsearch/search/geo/GeoBoundingBoxIT.java @@ -22,12 +22,12 @@ package org.elasticsearch.search.geo; import org.elasticsearch.action.search.SearchResponse; import org.elasticsearch.common.xcontent.XContentBuilder; import org.elasticsearch.common.xcontent.XContentFactory; +import org.elasticsearch.index.query.GeoValidationMethod; import org.elasticsearch.search.SearchHit; import org.elasticsearch.test.ESIntegTestCase; import org.junit.Test; import static org.elasticsearch.index.query.QueryBuilders.boolQuery; - import static org.elasticsearch.common.xcontent.XContentFactory.jsonBuilder; import static org.elasticsearch.index.query.QueryBuilders.*; import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertAcked; @@ -289,43 +289,43 @@ public class GeoBoundingBoxIT extends ESIntegTestCase { SearchResponse searchResponse = client().prepareSearch() .setQuery( - geoBoundingBoxQuery("location").coerce(true).setCorners(50, -180, -50, 180) + geoBoundingBoxQuery("location").setValidationMethod(GeoValidationMethod.COERCE).setCorners(50, -180, -50, 180) ).execute().actionGet(); assertThat(searchResponse.getHits().totalHits(), equalTo(1l)); searchResponse = client().prepareSearch() .setQuery( - geoBoundingBoxQuery("location").coerce(true).setCorners(50, -180, -50, 180).type("indexed") + geoBoundingBoxQuery("location").setValidationMethod(GeoValidationMethod.COERCE).setCorners(50, -180, -50, 180).type("indexed") ).execute().actionGet(); assertThat(searchResponse.getHits().totalHits(), equalTo(1l)); searchResponse = client().prepareSearch() .setQuery( - geoBoundingBoxQuery("location").coerce(true).setCorners(90, -180, -90, 180) + geoBoundingBoxQuery("location").setValidationMethod(GeoValidationMethod.COERCE).setCorners(90, -180, -90, 180) ).execute().actionGet(); assertThat(searchResponse.getHits().totalHits(), equalTo(2l)); searchResponse = client().prepareSearch() .setQuery( - geoBoundingBoxQuery("location").coerce(true).setCorners(90, -180, -90, 180).type("indexed") + geoBoundingBoxQuery("location").setValidationMethod(GeoValidationMethod.COERCE).setCorners(90, -180, -90, 180).type("indexed") ).execute().actionGet(); assertThat(searchResponse.getHits().totalHits(), equalTo(2l)); searchResponse = client().prepareSearch() .setQuery( - geoBoundingBoxQuery("location").coerce(true).setCorners(50, 0, -50, 360) + geoBoundingBoxQuery("location").setValidationMethod(GeoValidationMethod.COERCE).setCorners(50, 0, -50, 360) ).execute().actionGet(); assertThat(searchResponse.getHits().totalHits(), equalTo(1l)); searchResponse = client().prepareSearch() .setQuery( - geoBoundingBoxQuery("location").coerce(true).setCorners(50, 0, -50, 360).type("indexed") + geoBoundingBoxQuery("location").setValidationMethod(GeoValidationMethod.COERCE).setCorners(50, 0, -50, 360).type("indexed") ).execute().actionGet(); assertThat(searchResponse.getHits().totalHits(), equalTo(1l)); searchResponse = client().prepareSearch() .setQuery( - geoBoundingBoxQuery("location").coerce(true).setCorners(90, 0, -90, 360) + geoBoundingBoxQuery("location").setValidationMethod(GeoValidationMethod.COERCE).setCorners(90, 0, -90, 360) ).execute().actionGet(); assertThat(searchResponse.getHits().totalHits(), equalTo(2l)); searchResponse = client().prepareSearch() .setQuery( - geoBoundingBoxQuery("location").coerce(true).setCorners(90, 0, -90, 360).type("indexed") + geoBoundingBoxQuery("location").setValidationMethod(GeoValidationMethod.COERCE).setCorners(90, 0, -90, 360).type("indexed") ).execute().actionGet(); assertThat(searchResponse.getHits().totalHits(), equalTo(2l)); }