Skip to content

Commit 7648868

Browse files
imotovjkakavas
authored andcommitted
Geo: move indexShape to AbstractGeometryFieldMapper.Indexer (#44979)
Move indexShape functionality into AbstractGeometryFieldMapper to make it more unit testable. Relates to #43644
1 parent 393bf48 commit 7648868

11 files changed

+171
-170
lines changed

server/src/main/java/org/elasticsearch/index/mapper/AbstractGeometryFieldMapper.java

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@
4242

4343
import java.io.IOException;
4444
import java.text.ParseException;
45+
import java.util.ArrayList;
4546
import java.util.HashMap;
4647
import java.util.Iterator;
4748
import java.util.List;
@@ -78,6 +79,7 @@ public interface Indexer<Parsed, Processed> {
7879

7980
Class<Processed> processedClass();
8081

82+
List<IndexableField> indexShape(ParseContext context, Processed shape);
8183
}
8284

8385
/**
@@ -410,8 +412,6 @@ public Orientation orientation() {
410412
return ((AbstractGeometryFieldType)fieldType).orientation();
411413
}
412414

413-
protected abstract void indexShape(ParseContext context, Processed shape);
414-
415415
/** parsing logic for geometry indexing */
416416
@Override
417417
public void parse(ParseContext context) throws IOException {
@@ -428,7 +428,13 @@ public void parse(ParseContext context) throws IOException {
428428
}
429429
shape = geometryIndexer.prepareForIndexing(geometry);
430430
}
431-
indexShape(context, shape);
431+
432+
List<IndexableField> fields = new ArrayList<>();
433+
fields.addAll(geometryIndexer.indexShape(context, shape));
434+
createFieldNamesField(context, fields);
435+
for (IndexableField field : fields) {
436+
context.doc().add(field);
437+
}
432438
} catch (Exception e) {
433439
if (ignoreMalformed.value() == false) {
434440
throw new MapperParsingException("failed to parse field [{}] of type [{}]", e, fieldType().name(),

server/src/main/java/org/elasticsearch/index/mapper/GeoShapeFieldMapper.java

Lines changed: 7 additions & 122 deletions
Original file line numberDiff line numberDiff line change
@@ -18,29 +18,14 @@
1818
*/
1919
package org.elasticsearch.index.mapper;
2020

21-
import org.apache.lucene.document.Field;
2221
import org.apache.lucene.document.LatLonShape;
23-
import org.apache.lucene.geo.Line;
24-
import org.apache.lucene.geo.Polygon;
25-
import org.apache.lucene.index.IndexableField;
2622
import org.elasticsearch.common.Explicit;
2723
import org.elasticsearch.common.geo.GeometryParser;
2824
import org.elasticsearch.common.geo.builders.ShapeBuilder;
2925
import org.elasticsearch.common.settings.Settings;
30-
import org.elasticsearch.geo.geometry.Circle;
3126
import org.elasticsearch.geo.geometry.Geometry;
32-
import org.elasticsearch.geo.geometry.GeometryCollection;
33-
import org.elasticsearch.geo.geometry.GeometryVisitor;
34-
import org.elasticsearch.geo.geometry.LinearRing;
35-
import org.elasticsearch.geo.geometry.MultiLine;
36-
import org.elasticsearch.geo.geometry.MultiPoint;
37-
import org.elasticsearch.geo.geometry.MultiPolygon;
38-
import org.elasticsearch.geo.geometry.Point;
3927
import org.elasticsearch.index.query.VectorGeoShapeQueryProcessor;
4028

41-
import java.util.ArrayList;
42-
import java.util.Arrays;
43-
4429
/**
4530
* FieldMapper for indexing {@link LatLonShape}s.
4631
* <p>
@@ -80,12 +65,14 @@ public GeoShapeFieldMapper build(BuilderContext context) {
8065
protected void setupFieldType(BuilderContext context) {
8166
super.setupFieldType(context);
8267

83-
GeometryParser geometryParser = new GeometryParser(orientation == ShapeBuilder.Orientation.RIGHT, coerce(context).value(),
84-
ignoreZValue().value());
68+
GeoShapeFieldType fieldType = (GeoShapeFieldType)fieldType();
69+
boolean orientation = fieldType.orientation == ShapeBuilder.Orientation.RIGHT;
70+
71+
GeometryParser geometryParser = new GeometryParser(orientation, coerce(context).value(), ignoreZValue().value());
8572

86-
((GeoShapeFieldType)fieldType()).setGeometryIndexer(new GeoShapeIndexer(orientation == ShapeBuilder.Orientation.RIGHT));
87-
((GeoShapeFieldType)fieldType()).setGeometryParser( (parser, mapper) -> geometryParser.parse(parser));
88-
((GeoShapeFieldType)fieldType()).setGeometryQueryBuilder(new VectorGeoShapeQueryProcessor());
73+
fieldType.setGeometryIndexer(new GeoShapeIndexer(orientation, fieldType.name()));
74+
fieldType.setGeometryParser( (parser, mapper) -> geometryParser.parse(parser));
75+
fieldType.setGeometryQueryBuilder(new VectorGeoShapeQueryProcessor());
8976
}
9077
}
9178

@@ -107,11 +94,6 @@ public GeoShapeFieldType clone() {
10794
public String typeName() {
10895
return CONTENT_TYPE;
10996
}
110-
111-
@Override
112-
protected Indexer<Geometry, Geometry> geometryIndexer() {
113-
return new GeoShapeIndexer(orientation == ShapeBuilder.Orientation.RIGHT);
114-
}
11597
}
11698

11799
public GeoShapeFieldMapper(String simpleName, MappedFieldType fieldType, MappedFieldType defaultFieldType,
@@ -127,103 +109,6 @@ public GeoShapeFieldType fieldType() {
127109
return (GeoShapeFieldType) super.fieldType();
128110
}
129111

130-
@Override
131-
protected void indexShape(ParseContext context, Geometry luceneShape) {
132-
luceneShape.visit(new LuceneGeometryIndexer(context));
133-
}
134-
135-
private class LuceneGeometryIndexer implements GeometryVisitor<Void, RuntimeException> {
136-
private ParseContext context;
137-
138-
private LuceneGeometryIndexer(ParseContext context) {
139-
this.context = context;
140-
}
141-
142-
@Override
143-
public Void visit(Circle circle) {
144-
throw new IllegalArgumentException("invalid shape type found [Circle] while indexing shape");
145-
}
146-
147-
@Override
148-
public Void visit(GeometryCollection<?> collection) {
149-
for (Geometry geometry : collection) {
150-
geometry.visit(this);
151-
}
152-
return null;
153-
}
154-
155-
@Override
156-
public Void visit(org.elasticsearch.geo.geometry.Line line) {
157-
indexFields(context, LatLonShape.createIndexableFields(name(), new Line(line.getLats(), line.getLons())));
158-
return null;
159-
}
160-
161-
@Override
162-
public Void visit(LinearRing ring) {
163-
throw new IllegalArgumentException("invalid shape type found [LinearRing] while indexing shape");
164-
}
165-
166-
@Override
167-
public Void visit(MultiLine multiLine) {
168-
for (org.elasticsearch.geo.geometry.Line line : multiLine) {
169-
visit(line);
170-
}
171-
return null;
172-
}
173-
174-
@Override
175-
public Void visit(MultiPoint multiPoint) {
176-
for(Point point : multiPoint) {
177-
visit(point);
178-
}
179-
return null;
180-
}
181-
182-
@Override
183-
public Void visit(MultiPolygon multiPolygon) {
184-
for(org.elasticsearch.geo.geometry.Polygon polygon : multiPolygon) {
185-
visit(polygon);
186-
}
187-
return null;
188-
}
189-
190-
@Override
191-
public Void visit(Point point) {
192-
indexFields(context, LatLonShape.createIndexableFields(name(), point.getLat(), point.getLon()));
193-
return null;
194-
}
195-
196-
@Override
197-
public Void visit(org.elasticsearch.geo.geometry.Polygon polygon) {
198-
indexFields(context, LatLonShape.createIndexableFields(name(), toLucenePolygon(polygon)));
199-
return null;
200-
}
201-
202-
@Override
203-
public Void visit(org.elasticsearch.geo.geometry.Rectangle r) {
204-
Polygon p = new Polygon(new double[]{r.getMinLat(), r.getMinLat(), r.getMaxLat(), r.getMaxLat(), r.getMinLat()},
205-
new double[]{r.getMinLon(), r.getMaxLon(), r.getMaxLon(), r.getMinLon(), r.getMinLon()});
206-
indexFields(context, LatLonShape.createIndexableFields(name(), p));
207-
return null;
208-
}
209-
}
210-
211-
public static Polygon toLucenePolygon(org.elasticsearch.geo.geometry.Polygon polygon) {
212-
Polygon[] holes = new Polygon[polygon.getNumberOfHoles()];
213-
for(int i = 0; i<holes.length; i++) {
214-
holes[i] = new Polygon(polygon.getHole(i).getLats(), polygon.getHole(i).getLons());
215-
}
216-
return new Polygon(polygon.getPolygon().getLats(), polygon.getPolygon().getLons(), holes);
217-
}
218-
219-
private void indexFields(ParseContext context, Field[] fields) {
220-
ArrayList<IndexableField> flist = new ArrayList<>(Arrays.asList(fields));
221-
createFieldNamesField(context, flist);
222-
for (IndexableField f : flist) {
223-
context.doc().add(f);
224-
}
225-
}
226-
227112
@Override
228113
protected String contentType() {
229114
return CONTENT_TYPE;

server/src/main/java/org/elasticsearch/index/mapper/GeoShapeIndexer.java

Lines changed: 108 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@
2020

2121
package org.elasticsearch.index.mapper;
2222

23+
import org.apache.lucene.document.LatLonShape;
24+
import org.apache.lucene.index.IndexableField;
2325
import org.elasticsearch.common.collect.Tuple;
2426
import org.elasticsearch.geo.geometry.Circle;
2527
import org.elasticsearch.geo.geometry.Geometry;
@@ -60,8 +62,11 @@ public final class GeoShapeIndexer implements AbstractGeometryFieldMapper.Indexe
6062

6163
private final boolean orientation;
6264

63-
public GeoShapeIndexer(boolean orientation) {
65+
private final String name;
66+
67+
public GeoShapeIndexer(boolean orientation, String name) {
6468
this.orientation = orientation;
69+
this.name = name;
6570
}
6671

6772
public Geometry prepareForIndexing(Geometry geometry) {
@@ -181,6 +186,13 @@ public Class<Geometry> processedClass() {
181186
return Geometry.class;
182187
}
183188

189+
@Override
190+
public List<IndexableField> indexShape(ParseContext context, Geometry shape) {
191+
LuceneGeometryIndexer visitor = new LuceneGeometryIndexer(name);
192+
shape.visit(visitor);
193+
return visitor.fields();
194+
}
195+
184196
/**
185197
* Calculate the intersection of a line segment and a vertical dateline.
186198
*
@@ -936,4 +948,99 @@ private static Point[][] holes(Edge[] holes, int numHoles) {
936948
return points;
937949
}
938950

951+
952+
private static class LuceneGeometryIndexer implements GeometryVisitor<Void, RuntimeException> {
953+
private List<IndexableField> fields = new ArrayList<>();
954+
private String name;
955+
956+
private LuceneGeometryIndexer(String name) {
957+
this.name = name;
958+
}
959+
960+
List<IndexableField> fields() {
961+
return fields;
962+
}
963+
964+
@Override
965+
public Void visit(Circle circle) {
966+
throw new IllegalArgumentException("invalid shape type found [Circle] while indexing shape");
967+
}
968+
969+
@Override
970+
public Void visit(GeometryCollection<?> collection) {
971+
for (Geometry geometry : collection) {
972+
geometry.visit(this);
973+
}
974+
return null;
975+
}
976+
977+
@Override
978+
public Void visit(org.elasticsearch.geo.geometry.Line line) {
979+
addFields(LatLonShape.createIndexableFields(name, new org.apache.lucene.geo.Line(line.getLats(), line.getLons())));
980+
return null;
981+
}
982+
983+
@Override
984+
public Void visit(LinearRing ring) {
985+
throw new IllegalArgumentException("invalid shape type found [LinearRing] while indexing shape");
986+
}
987+
988+
@Override
989+
public Void visit(MultiLine multiLine) {
990+
for (org.elasticsearch.geo.geometry.Line line : multiLine) {
991+
visit(line);
992+
}
993+
return null;
994+
}
995+
996+
@Override
997+
public Void visit(MultiPoint multiPoint) {
998+
for(Point point : multiPoint) {
999+
visit(point);
1000+
}
1001+
return null;
1002+
}
1003+
1004+
@Override
1005+
public Void visit(MultiPolygon multiPolygon) {
1006+
for(org.elasticsearch.geo.geometry.Polygon polygon : multiPolygon) {
1007+
visit(polygon);
1008+
}
1009+
return null;
1010+
}
1011+
1012+
@Override
1013+
public Void visit(Point point) {
1014+
addFields(LatLonShape.createIndexableFields(name, point.getLat(), point.getLon()));
1015+
return null;
1016+
}
1017+
1018+
@Override
1019+
public Void visit(org.elasticsearch.geo.geometry.Polygon polygon) {
1020+
addFields(LatLonShape.createIndexableFields(name, toLucenePolygon(polygon)));
1021+
return null;
1022+
}
1023+
1024+
@Override
1025+
public Void visit(org.elasticsearch.geo.geometry.Rectangle r) {
1026+
org.apache.lucene.geo.Polygon p = new org.apache.lucene.geo.Polygon(
1027+
new double[]{r.getMinLat(), r.getMinLat(), r.getMaxLat(), r.getMaxLat(), r.getMinLat()},
1028+
new double[]{r.getMinLon(), r.getMaxLon(), r.getMaxLon(), r.getMinLon(), r.getMinLon()});
1029+
addFields(LatLonShape.createIndexableFields(name, p));
1030+
return null;
1031+
}
1032+
1033+
private void addFields(IndexableField[] fields) {
1034+
this.fields.addAll(Arrays.asList(fields));
1035+
}
1036+
}
1037+
1038+
1039+
public static org.apache.lucene.geo.Polygon toLucenePolygon(org.elasticsearch.geo.geometry.Polygon polygon) {
1040+
org.apache.lucene.geo.Polygon[] holes = new org.apache.lucene.geo.Polygon[polygon.getNumberOfHoles()];
1041+
for(int i = 0; i<holes.length; i++) {
1042+
holes[i] = new org.apache.lucene.geo.Polygon(polygon.getHole(i).getLats(), polygon.getHole(i).getLons());
1043+
}
1044+
return new org.apache.lucene.geo.Polygon(polygon.getPolygon().getLats(), polygon.getPolygon().getLons(), holes);
1045+
}
9391046
}

0 commit comments

Comments
 (0)