From 7164750fecabc8c250a9d0dba0f0f317162a742d Mon Sep 17 00:00:00 2001 From: marko-bekhta Date: Fri, 10 Nov 2023 13:36:46 +0100 Subject: [PATCH] HSEARCH-4999 Use geo_shape instead of geo_polygon in Elasticsearch spatial predicates --- ...GeoPointSpatialWithinPolygonPredicate.java | 38 +++++++++++++++---- 1 file changed, 30 insertions(+), 8 deletions(-) diff --git a/backend/elasticsearch/src/main/java/org/hibernate/search/backend/elasticsearch/types/predicate/impl/ElasticsearchGeoPointSpatialWithinPolygonPredicate.java b/backend/elasticsearch/src/main/java/org/hibernate/search/backend/elasticsearch/types/predicate/impl/ElasticsearchGeoPointSpatialWithinPolygonPredicate.java index 83529162289..67c74112d8c 100644 --- a/backend/elasticsearch/src/main/java/org/hibernate/search/backend/elasticsearch/types/predicate/impl/ElasticsearchGeoPointSpatialWithinPolygonPredicate.java +++ b/backend/elasticsearch/src/main/java/org/hibernate/search/backend/elasticsearch/types/predicate/impl/ElasticsearchGeoPointSpatialWithinPolygonPredicate.java @@ -25,12 +25,15 @@ public class ElasticsearchGeoPointSpatialWithinPolygonPredicate extends AbstractElasticsearchSingleFieldPredicate { - private static final JsonObjectAccessor GEO_POLYGON_ACCESSOR = - JsonAccessor.root().property( "geo_polygon" ).asObject(); + private static final JsonObjectAccessor GEO_SHAPE_ACCESSOR = + JsonAccessor.root().property( "geo_shape" ).asObject(); private static final JsonAccessor IGNORE_UNMAPPED_ACCESSOR = JsonAccessor.root().property( "ignore_unmapped" ).asBoolean(); - private static final String POINTS_PROPERTY_NAME = "points"; + private static final String COORDINATES_PROPERTY_NAME = "coordinates"; + private static final String TYPE_PROPERTY_NAME = "type"; + private static final String TYPE_PROPERTY_VALUE = "Polygon"; + private static final String SHAPE_PROPERTY_NAME = "shape"; private final double[] coordinates; @@ -42,7 +45,7 @@ private ElasticsearchGeoPointSpatialWithinPolygonPredicate(Builder builder) { @Override protected JsonObject doToJsonQuery(PredicateRequestContext context, JsonObject outerObject, JsonObject innerObject) { - JsonObject pointsObject = new JsonObject(); + JsonObject geometryObject = new JsonObject(); JsonArray pointsArray = new JsonArray(); for ( int i = 0; i < coordinates.length; i += 2 ) { JsonArray point = new JsonArray(); @@ -50,9 +53,28 @@ protected JsonObject doToJsonQuery(PredicateRequestContext context, JsonObject o point.add( coordinates[i + 1] ); pointsArray.add( point ); } - pointsObject.add( POINTS_PROPERTY_NAME, pointsArray ); - - innerObject.add( absoluteFieldPath, pointsObject ); + // GeoJSON Polygon has an array around the array of actual coordinates: + // "geometry": { + // "type": "Polygon", + // "coordinates": [ + // [ + // [100.0, 0.0], + // [101.0, 0.0], + // [101.0, 1.0], + // [100.0, 1.0], + // [100.0, 0.0] + // ] + // ] + // }, + JsonArray coordinatesArray = new JsonArray(); + coordinatesArray.add( pointsArray ); + geometryObject.add( COORDINATES_PROPERTY_NAME, coordinatesArray ); + // A GeoJSON shape; in our case we'll always have a Polygon: + geometryObject.addProperty( TYPE_PROPERTY_NAME, TYPE_PROPERTY_VALUE ); + + JsonObject shapeObject = new JsonObject(); + shapeObject.add( SHAPE_PROPERTY_NAME, geometryObject ); + innerObject.add( absoluteFieldPath, shapeObject ); if ( indexNames().size() > 1 ) { // There are multiple target indexes; some of them may not declare the field. @@ -60,7 +82,7 @@ protected JsonObject doToJsonQuery(PredicateRequestContext context, JsonObject o IGNORE_UNMAPPED_ACCESSOR.set( innerObject, true ); } - GEO_POLYGON_ACCESSOR.set( outerObject, innerObject ); + GEO_SHAPE_ACCESSOR.set( outerObject, innerObject ); return outerObject; }