Skip to content

Commit 744ca26

Browse files
authored
Revert changes in AbstractPointGeometryFieldMapper (#5250)
The change made in AbstractPointGeometryFieldMapper class with commit 0503897 introduced a performace degradation during point data indexing. Reverting it therefore. The change is about consolidating array format parsing code for point type in a single place to acheive following benefits. 1. Allow plugins to override array parsing logic. Plugins can add its own parsing logic for point field by providing object parser. However, it cannot override array format. Therefore, plugin have to use whatever implemented in AbstractPointGeometryFieldMapper class. 2. Enhanced code quality by removing duplicated code There is no change in functionality because 1. There is no change in functionality in OpenSearch and 2. No plugins have its own parsing logic for point data in array format yet. Signed-off-by: Heemin Kim <heemin@amazon.com> Signed-off-by: Heemin Kim <heemin@amazon.com>
1 parent 94c5bd7 commit 744ca26

File tree

2 files changed

+22
-58
lines changed

2 files changed

+22
-58
lines changed

server/src/main/java/org/opensearch/index/mapper/AbstractPointGeometryFieldMapper.java

Lines changed: 22 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -36,14 +36,11 @@
3636
import org.opensearch.common.CheckedBiFunction;
3737
import org.opensearch.common.Explicit;
3838
import org.opensearch.common.ParseField;
39-
import org.opensearch.common.bytes.BytesReference;
39+
import org.opensearch.common.geo.GeoPoint;
4040
import org.opensearch.common.geo.GeometryFormat;
4141
import org.opensearch.common.geo.GeometryParser;
42-
import org.opensearch.common.xcontent.DeprecationHandler;
4342
import org.opensearch.common.xcontent.LoggingDeprecationHandler;
44-
import org.opensearch.common.xcontent.NamedXContentRegistry;
4543
import org.opensearch.common.xcontent.XContentBuilder;
46-
import org.opensearch.common.xcontent.XContentFactory;
4744
import org.opensearch.common.xcontent.XContentParser;
4845
import org.opensearch.geometry.Geometry;
4946
import org.opensearch.geometry.Point;
@@ -245,7 +242,6 @@ default boolean isNormalizable(double coord) {
245242
* @opensearch.internal
246243
*/
247244
public static class PointParser<P extends ParsedPoint> extends Parser<List<P>> {
248-
private static final int MAX_NUMBER_OF_VALUES_IN_ARRAY_FORMAT = 3;
249245
/**
250246
* Note that this parser is only used for formatting values.
251247
*/
@@ -285,27 +281,32 @@ private P process(P in) {
285281

286282
@Override
287283
public List<P> parse(XContentParser parser) throws IOException, ParseException {
284+
288285
if (parser.currentToken() == XContentParser.Token.START_ARRAY) {
289-
parser.nextToken();
290-
if (parser.currentToken() == XContentParser.Token.VALUE_NUMBER) {
291-
XContentBuilder xContentBuilder = reconstructArrayXContent(parser);
292-
try (
293-
XContentParser subParser = createParser(
294-
parser.getXContentRegistry(),
295-
parser.getDeprecationHandler(),
296-
xContentBuilder
297-
);
298-
) {
299-
return Collections.singletonList(process(objectParser.apply(subParser, pointSupplier.get())));
286+
XContentParser.Token token = parser.nextToken();
287+
P point = pointSupplier.get();
288+
ArrayList<P> points = new ArrayList<>();
289+
if (token == XContentParser.Token.VALUE_NUMBER) {
290+
double x = parser.doubleValue();
291+
parser.nextToken();
292+
double y = parser.doubleValue();
293+
token = parser.nextToken();
294+
if (token == XContentParser.Token.VALUE_NUMBER) {
295+
GeoPoint.assertZValue(ignoreZValue, parser.doubleValue());
296+
} else if (token != XContentParser.Token.END_ARRAY) {
297+
throw new OpenSearchParseException("field type does not accept > 3 dimensions");
300298
}
299+
300+
point.resetCoords(x, y);
301+
points.add(process(point));
301302
} else {
302-
ArrayList<P> points = new ArrayList<>();
303-
while (parser.currentToken() != XContentParser.Token.END_ARRAY) {
304-
points.add(process(objectParser.apply(parser, pointSupplier.get())));
305-
parser.nextToken();
303+
while (token != XContentParser.Token.END_ARRAY) {
304+
points.add(process(objectParser.apply(parser, point)));
305+
point = pointSupplier.get();
306+
token = parser.nextToken();
306307
}
307-
return points;
308308
}
309+
return points;
309310
} else if (parser.currentToken() == XContentParser.Token.VALUE_NULL) {
310311
if (nullValue == null) {
311312
return null;
@@ -317,37 +318,6 @@ public List<P> parse(XContentParser parser) throws IOException, ParseException {
317318
}
318319
}
319320

320-
private XContentParser createParser(
321-
NamedXContentRegistry namedXContentRegistry,
322-
DeprecationHandler deprecationHandler,
323-
XContentBuilder xContentBuilder
324-
) throws IOException {
325-
XContentParser subParser = xContentBuilder.contentType()
326-
.xContent()
327-
.createParser(namedXContentRegistry, deprecationHandler, BytesReference.bytes(xContentBuilder).streamInput());
328-
subParser.nextToken();
329-
return subParser;
330-
}
331-
332-
private XContentBuilder reconstructArrayXContent(XContentParser parser) throws IOException {
333-
XContentBuilder builder = XContentFactory.jsonBuilder().startArray();
334-
int numberOfValuesAdded = 0;
335-
while (parser.currentToken() != XContentParser.Token.END_ARRAY) {
336-
if (parser.currentToken() != XContentParser.Token.VALUE_NUMBER) {
337-
throw new OpenSearchParseException("numeric value expected");
338-
}
339-
builder.value(parser.doubleValue());
340-
parser.nextToken();
341-
342-
// Allows one more value to be added so that the error case can be handled by a parser
343-
if (++numberOfValuesAdded > MAX_NUMBER_OF_VALUES_IN_ARRAY_FORMAT) {
344-
break;
345-
}
346-
}
347-
builder.endArray();
348-
return builder;
349-
}
350-
351321
@Override
352322
public Object format(List<P> points, String format) {
353323
List<Object> result = new ArrayList<>();

server/src/test/java/org/opensearch/index/mapper/GeoPointFieldMapperTests.java

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -164,12 +164,6 @@ public void testLatLonInOneValueArray() throws Exception {
164164
assertThat(doc.rootDoc().getFields("field"), arrayWithSize(4));
165165
}
166166

167-
public void testLatLonInArrayMoreThanThreeValues() throws Exception {
168-
DocumentMapper mapper = createDocumentMapper(fieldMapping(b -> b.field("type", "geo_point").field("ignore_z_value", true)));
169-
Exception e = expectThrows(MapperParsingException.class, () -> mapper.parse(source(b -> b.array("field", 1.2, 1.3, 1.4, 1.5))));
170-
assertThat(e.getCause().getMessage(), containsString("[geo_point] field type does not accept more than 3 values"));
171-
}
172-
173167
public void testLonLatArray() throws Exception {
174168
DocumentMapper mapper = createDocumentMapper(fieldMapping(this::minimalMapping));
175169
ParsedDocument doc = mapper.parse(source(b -> b.startArray("field").value(1.3).value(1.2).endArray()));

0 commit comments

Comments
 (0)