mirror of
https://github.com/honeymoose/OpenSearch.git
synced 2025-02-17 10:25:15 +00:00
[GEO] fix pointsOnly bug for MULTIPOINT
This commit fixes a bug where geo_shape indexes configured for "points_only" : "true" reject documents containing multipoint shape types.
This commit is contained in:
parent
858b2c7cb8
commit
075c77fc81
@ -34,6 +34,7 @@ import org.elasticsearch.Version;
|
||||
import org.elasticsearch.common.Explicit;
|
||||
import org.elasticsearch.common.geo.GeoUtils;
|
||||
import org.elasticsearch.common.geo.SpatialStrategy;
|
||||
import org.elasticsearch.common.geo.XShapeCollection;
|
||||
import org.elasticsearch.common.geo.builders.ShapeBuilder;
|
||||
import org.elasticsearch.common.geo.builders.ShapeBuilder.Orientation;
|
||||
import org.elasticsearch.common.geo.parsers.ShapeParser;
|
||||
@ -463,7 +464,6 @@ public class GeoShapeFieldMapper extends FieldMapper {
|
||||
public GeoShapeFieldType fieldType() {
|
||||
return (GeoShapeFieldType) super.fieldType();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Mapper parse(ParseContext context) throws IOException {
|
||||
try {
|
||||
@ -475,14 +475,20 @@ public class GeoShapeFieldMapper extends FieldMapper {
|
||||
}
|
||||
shape = shapeBuilder.build();
|
||||
}
|
||||
if (fieldType().pointsOnly() && !(shape instanceof Point)) {
|
||||
throw new MapperParsingException("[{" + fieldType().name() + "}] is configured for points only but a " +
|
||||
((shape instanceof JtsGeometry) ? ((JtsGeometry) shape).getGeom().getGeometryType() : shape.getClass()) + " was found");
|
||||
}
|
||||
List<IndexableField> fields = new ArrayList<>(Arrays.asList(fieldType().defaultStrategy().createIndexableFields(shape)));
|
||||
createFieldNamesField(context, fields);
|
||||
for (IndexableField field : fields) {
|
||||
context.doc().add(field);
|
||||
if (fieldType().pointsOnly() == true) {
|
||||
// index configured for pointsOnly
|
||||
if (shape instanceof XShapeCollection && XShapeCollection.class.cast(shape).pointsOnly()) {
|
||||
// MULTIPOINT data: index each point separately
|
||||
List<Shape> shapes = ((XShapeCollection) shape).getShapes();
|
||||
for (Shape s : shapes) {
|
||||
indexShape(context, s);
|
||||
}
|
||||
} else if (shape instanceof Point == false) {
|
||||
throw new MapperParsingException("[{" + fieldType().name() + "}] is configured for points only but a " +
|
||||
((shape instanceof JtsGeometry) ? ((JtsGeometry)shape).getGeom().getGeometryType() : shape.getClass()) + " was found");
|
||||
}
|
||||
} else {
|
||||
indexShape(context, shape);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
if (ignoreMalformed.value() == false) {
|
||||
@ -492,6 +498,14 @@ public class GeoShapeFieldMapper extends FieldMapper {
|
||||
return null;
|
||||
}
|
||||
|
||||
private void indexShape(ParseContext context, Shape shape) {
|
||||
List<IndexableField> fields = new ArrayList<>(Arrays.asList(fieldType().defaultStrategy().createIndexableFields(shape)));
|
||||
createFieldNamesField(context, fields);
|
||||
for (IndexableField field : fields) {
|
||||
context.doc().add(field);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void parseCreateField(ParseContext context, List<IndexableField> fields) throws IOException {
|
||||
}
|
||||
|
@ -48,6 +48,7 @@ import static org.elasticsearch.action.support.WriteRequest.RefreshPolicy.IMMEDI
|
||||
import static org.elasticsearch.common.xcontent.XContentFactory.jsonBuilder;
|
||||
import static org.elasticsearch.index.query.QueryBuilders.geoIntersectionQuery;
|
||||
import static org.elasticsearch.index.query.QueryBuilders.geoShapeQuery;
|
||||
import static org.elasticsearch.index.query.QueryBuilders.matchAllQuery;
|
||||
import static org.elasticsearch.test.geo.RandomShapeGenerator.createGeometryCollectionWithin;
|
||||
import static org.elasticsearch.test.geo.RandomShapeGenerator.xRandomPoint;
|
||||
import static org.elasticsearch.test.geo.RandomShapeGenerator.xRandomRectangle;
|
||||
@ -468,4 +469,38 @@ public class GeoShapeQueryTests extends ESSingleNodeTestCase {
|
||||
|
||||
assertEquals(1, response.getHits().getTotalHits());
|
||||
}
|
||||
|
||||
public void testPointsOnlyExplicit() throws Exception {
|
||||
String mapping = XContentFactory.jsonBuilder().startObject().startObject("type1")
|
||||
.startObject("properties").startObject("location")
|
||||
.field("type", "geo_shape")
|
||||
.field("tree", randomBoolean() ? "quadtree" : "geohash")
|
||||
.field("tree_levels", "6")
|
||||
.field("distance_error_pct", "0.01")
|
||||
.field("points_only", true)
|
||||
.endObject().endObject()
|
||||
.endObject().endObject().string();
|
||||
|
||||
client().admin().indices().prepareCreate("geo_points_only").addMapping("type1", mapping, XContentType.JSON).execute().actionGet();
|
||||
ensureGreen();
|
||||
|
||||
// MULTIPOINT
|
||||
ShapeBuilder shape = RandomShapeGenerator.createShape(random(), RandomShapeGenerator.ShapeType.MULTIPOINT);
|
||||
client().prepareIndex("geo_points_only", "type1", "1")
|
||||
.setSource(jsonBuilder().startObject().field("location", shape).endObject())
|
||||
.setRefreshPolicy(IMMEDIATE).get();
|
||||
|
||||
// POINT
|
||||
shape = RandomShapeGenerator.createShape(random(), RandomShapeGenerator.ShapeType.POINT);
|
||||
client().prepareIndex("geo_points_only", "type1", "2")
|
||||
.setSource(jsonBuilder().startObject().field("location", shape).endObject())
|
||||
.setRefreshPolicy(IMMEDIATE).get();
|
||||
|
||||
// test that point was inserted
|
||||
SearchResponse response = client().prepareSearch("geo_points_only").setTypes("type1")
|
||||
.setQuery(matchAllQuery())
|
||||
.execute().actionGet();
|
||||
|
||||
assertEquals(2, response.getHits().getTotalHits());
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user