Geo: add Geometry-based query builders to QueryBuilders (#45058)

Add Geometry-based method for creation of query builders in
QueryBuilder

Relates to #44715
This commit is contained in:
Igor Motov 2019-08-02 14:34:02 -04:00
parent 3df1c76f9b
commit b5f88120b5
3 changed files with 62 additions and 11 deletions

View File

@ -24,6 +24,7 @@ import org.elasticsearch.common.bytes.BytesReference;
import org.elasticsearch.common.geo.GeoPoint;
import org.elasticsearch.common.geo.ShapeRelation;
import org.elasticsearch.common.geo.builders.ShapeBuilder;
import org.elasticsearch.geo.geometry.Geometry;
import org.elasticsearch.index.query.MoreLikeThisQueryBuilder.Item;
import org.elasticsearch.index.query.functionscore.FunctionScoreQueryBuilder;
import org.elasticsearch.index.query.functionscore.ScoreFunctionBuilder;
@ -648,6 +649,14 @@ public final class QueryBuilders {
* @param name The shape field name
* @param shape Shape to use in the filter
*/
public static GeoShapeQueryBuilder geoShapeQuery(String name, Geometry shape) throws IOException {
return new GeoShapeQueryBuilder(name, shape);
}
/**
* @deprecated use {@link #geoShapeQuery(String, Geometry)} instead
*/
@Deprecated
public static GeoShapeQueryBuilder geoShapeQuery(String name, ShapeBuilder shape) throws IOException {
return new GeoShapeQueryBuilder(name, shape);
}
@ -670,6 +679,16 @@ public final class QueryBuilders {
* @param name The shape field name
* @param shape Shape to use in the filter
*/
public static GeoShapeQueryBuilder geoIntersectionQuery(String name, Geometry shape) throws IOException {
GeoShapeQueryBuilder builder = geoShapeQuery(name, shape);
builder.relation(ShapeRelation.INTERSECTS);
return builder;
}
/**
* @deprecated use {@link #geoIntersectionQuery(String, Geometry)} instead
*/
@Deprecated
public static GeoShapeQueryBuilder geoIntersectionQuery(String name, ShapeBuilder shape) throws IOException {
GeoShapeQueryBuilder builder = geoShapeQuery(name, shape);
builder.relation(ShapeRelation.INTERSECTS);
@ -698,6 +717,16 @@ public final class QueryBuilders {
* @param name The shape field name
* @param shape Shape to use in the filter
*/
public static GeoShapeQueryBuilder geoWithinQuery(String name, Geometry shape) throws IOException {
GeoShapeQueryBuilder builder = geoShapeQuery(name, shape);
builder.relation(ShapeRelation.WITHIN);
return builder;
}
/**
* @deprecated use {@link #geoWithinQuery(String, Geometry)} instead
*/
@Deprecated
public static GeoShapeQueryBuilder geoWithinQuery(String name, ShapeBuilder shape) throws IOException {
GeoShapeQueryBuilder builder = geoShapeQuery(name, shape);
builder.relation(ShapeRelation.WITHIN);
@ -726,6 +755,16 @@ public final class QueryBuilders {
* @param name The shape field name
* @param shape Shape to use in the filter
*/
public static GeoShapeQueryBuilder geoDisjointQuery(String name, Geometry shape) throws IOException {
GeoShapeQueryBuilder builder = geoShapeQuery(name, shape);
builder.relation(ShapeRelation.DISJOINT);
return builder;
}
/**
* @deprecated use {@link #geoDisjointQuery(String, Geometry)} instead
*/
@Deprecated
public static GeoShapeQueryBuilder geoDisjointQuery(String name, ShapeBuilder shape) throws IOException {
GeoShapeQueryBuilder builder = geoShapeQuery(name, shape);
builder.relation(ShapeRelation.DISJOINT);

View File

@ -199,7 +199,9 @@ public class GeoShapeQueryBuilderTests extends AbstractQueryTestCase<GeoShapeQue
// see #3878
public void testThatXContentSerializationInsideOfArrayWorks() throws Exception {
EnvelopeBuilder envelopeBuilder = new EnvelopeBuilder(new Coordinate(0, 10), new Coordinate(10, 0));
GeoShapeQueryBuilder geoQuery = QueryBuilders.geoShapeQuery("searchGeometry", envelopeBuilder);
GeoShapeQueryBuilder geoQuery = randomBoolean() ?
QueryBuilders.geoShapeQuery("searchGeometry", envelopeBuilder) :
QueryBuilders.geoShapeQuery("searchGeometry", envelopeBuilder.buildGeometry());
JsonXContent.contentBuilder().startArray().value(geoQuery).endArray();
}
@ -230,7 +232,9 @@ public class GeoShapeQueryBuilderTests extends AbstractQueryTestCase<GeoShapeQue
UnsupportedOperationException e = expectThrows(UnsupportedOperationException.class, () -> query.toQuery(createShardContext()));
assertEquals("query must be rewritten first", e.getMessage());
QueryBuilder rewrite = rewriteAndFetch(query, createShardContext());
GeoShapeQueryBuilder geoShapeQueryBuilder = new GeoShapeQueryBuilder(fieldName(), indexedShapeToReturn);
GeoShapeQueryBuilder geoShapeQueryBuilder = randomBoolean() ?
new GeoShapeQueryBuilder(fieldName(), indexedShapeToReturn) :
new GeoShapeQueryBuilder(fieldName(), indexedShapeToReturn.buildGeometry());
geoShapeQueryBuilder.strategy(query.strategy());
geoShapeQueryBuilder.relation(query.relation());
assertEquals(geoShapeQueryBuilder, rewrite);
@ -244,7 +248,9 @@ public class GeoShapeQueryBuilderTests extends AbstractQueryTestCase<GeoShapeQue
builder = rewriteAndFetch(builder, createShardContext());
GeoShapeQueryBuilder expectedShape = new GeoShapeQueryBuilder(fieldName(), indexedShapeToReturn);
GeoShapeQueryBuilder expectedShape = randomBoolean() ?
new GeoShapeQueryBuilder(fieldName(), indexedShapeToReturn) :
new GeoShapeQueryBuilder(fieldName(), indexedShapeToReturn.buildGeometry());
expectedShape.strategy(shape.strategy());
expectedShape.relation(shape.relation());
QueryBuilder expected = new BoolQueryBuilder()
@ -256,13 +262,17 @@ public class GeoShapeQueryBuilderTests extends AbstractQueryTestCase<GeoShapeQue
public void testIgnoreUnmapped() throws IOException {
ShapeType shapeType = ShapeType.randomType(random());
ShapeBuilder<?, ?, ?> shape = RandomShapeGenerator.createShapeWithin(random(), null, shapeType);
final GeoShapeQueryBuilder queryBuilder = new GeoShapeQueryBuilder("unmapped", shape);
final GeoShapeQueryBuilder queryBuilder = randomBoolean() ?
new GeoShapeQueryBuilder("unmapped", shape) :
new GeoShapeQueryBuilder("unmapped", shape.buildGeometry());
queryBuilder.ignoreUnmapped(true);
Query query = queryBuilder.toQuery(createShardContext());
assertThat(query, notNullValue());
assertThat(query, instanceOf(MatchNoDocsQuery.class));
final GeoShapeQueryBuilder failingQueryBuilder = new GeoShapeQueryBuilder("unmapped", shape);
final GeoShapeQueryBuilder failingQueryBuilder = randomBoolean() ?
new GeoShapeQueryBuilder("unmapped", shape) :
new GeoShapeQueryBuilder("unmapped", shape.buildGeometry());
failingQueryBuilder.ignoreUnmapped(false);
QueryShardException e = expectThrows(QueryShardException.class, () -> failingQueryBuilder.toQuery(createShardContext()));
assertThat(e.getMessage(), containsString("failed to find geo_shape field [unmapped]"));
@ -271,7 +281,9 @@ public class GeoShapeQueryBuilderTests extends AbstractQueryTestCase<GeoShapeQue
public void testWrongFieldType() throws IOException {
ShapeType shapeType = ShapeType.randomType(random());
ShapeBuilder<?, ?, ?> shape = RandomShapeGenerator.createShapeWithin(random(), null, shapeType);
final GeoShapeQueryBuilder queryBuilder = new GeoShapeQueryBuilder(STRING_FIELD_NAME, shape);
final GeoShapeQueryBuilder queryBuilder = randomBoolean() ?
new GeoShapeQueryBuilder(STRING_FIELD_NAME, shape) :
new GeoShapeQueryBuilder(STRING_FIELD_NAME, shape.buildGeometry());
QueryShardException e = expectThrows(QueryShardException.class, () -> queryBuilder.toQuery(createShardContext()));
assertThat(e.getMessage(), containsString("Field [mapped_string] is not of type [geo_shape] but of type [text]"));
}

View File

@ -317,7 +317,7 @@ public class GeoFilterIT extends ESIntegTestCase {
result = client().prepareSearch()
.setQuery(matchAllQuery())
.setPostFilter(QueryBuilders.geoWithinQuery("area", builder))
.setPostFilter(QueryBuilders.geoWithinQuery("area", builder.buildGeometry()))
.get();
assertHitCount(result, 2);
}
@ -342,25 +342,25 @@ public class GeoFilterIT extends ESIntegTestCase {
result = client().prepareSearch()
.setQuery(matchAllQuery())
.setPostFilter(QueryBuilders.geoIntersectionQuery("area", new PointBuilder(174, -4)))
.setPostFilter(QueryBuilders.geoIntersectionQuery("area", new PointBuilder(174, -4).buildGeometry()))
.get();
assertHitCount(result, 1);
result = client().prepareSearch()
.setQuery(matchAllQuery())
.setPostFilter(QueryBuilders.geoIntersectionQuery("area", new PointBuilder(-174, -4)))
.setPostFilter(QueryBuilders.geoIntersectionQuery("area", new PointBuilder(-174, -4).buildGeometry()))
.get();
assertHitCount(result, 1);
result = client().prepareSearch()
.setQuery(matchAllQuery())
.setPostFilter(QueryBuilders.geoIntersectionQuery("area", new PointBuilder(180, -4)))
.setPostFilter(QueryBuilders.geoIntersectionQuery("area", new PointBuilder(180, -4).buildGeometry()))
.get();
assertHitCount(result, 0);
result = client().prepareSearch()
.setQuery(matchAllQuery())
.setPostFilter(QueryBuilders.geoIntersectionQuery("area", new PointBuilder(180, -6)))
.setPostFilter(QueryBuilders.geoIntersectionQuery("area", new PointBuilder(180, -6).buildGeometry()))
.get();
assertHitCount(result, 1);
}