From ba3de9274d1a22357378ffdf825a93622e3b6b11 Mon Sep 17 00:00:00 2001 From: Jack Conradson Date: Mon, 6 Dec 2021 14:36:39 -0800 Subject: [PATCH 1/7] Add a geo point field for the scripting fields api --- .../org.elasticsearch.script.fields.txt | 5 + .../painless/org.elasticsearch.txt | 2 + .../test/painless/50_script_doc_values.yml | 61 +++++++ .../index/fielddata/ScriptDocValues.java | 12 +- .../index/mapper/GeoPointFieldMapper.java | 7 +- .../script/field/GeoPointDocValuesField.java | 164 ++++++++++++++++++ .../AbstractAtomicGeoShapeShapeFieldData.java | 8 +- 7 files changed, 244 insertions(+), 15 deletions(-) create mode 100644 server/src/main/java/org/elasticsearch/script/field/GeoPointDocValuesField.java diff --git a/modules/lang-painless/src/main/resources/org/elasticsearch/painless/org.elasticsearch.script.fields.txt b/modules/lang-painless/src/main/resources/org/elasticsearch/painless/org.elasticsearch.script.fields.txt index c71a87732a5b5..6c70c370001b7 100644 --- a/modules/lang-painless/src/main/resources/org/elasticsearch/painless/org.elasticsearch.script.fields.txt +++ b/modules/lang-painless/src/main/resources/org/elasticsearch/painless/org.elasticsearch.script.fields.txt @@ -82,3 +82,8 @@ class org.elasticsearch.script.field.KeywordDocValuesField @dynamic_type { String get(String) String get(int, String) } + +class org.elasticsearch.script.field.GeoPointDocValuesField @dynamic_type { + GeoPoint get(GeoPoint) + GeoPoint get(int, GeoPoint) +} diff --git a/modules/lang-painless/src/main/resources/org/elasticsearch/painless/org.elasticsearch.txt b/modules/lang-painless/src/main/resources/org/elasticsearch/painless/org.elasticsearch.txt index 907a98be5b973..0aabbb2b097ab 100644 --- a/modules/lang-painless/src/main/resources/org/elasticsearch/painless/org.elasticsearch.txt +++ b/modules/lang-painless/src/main/resources/org/elasticsearch/painless/org.elasticsearch.txt @@ -49,6 +49,8 @@ class org.elasticsearch.painless.api.Debug { #### ES Scripting API class org.elasticsearch.common.geo.GeoPoint { + () + (double, double) double getLat() double getLon() } diff --git a/modules/lang-painless/src/yamlRestTest/resources/rest-api-spec/test/painless/50_script_doc_values.yml b/modules/lang-painless/src/yamlRestTest/resources/rest-api-spec/test/painless/50_script_doc_values.yml index 8a1f9702f3214..c6502796b593a 100644 --- a/modules/lang-painless/src/yamlRestTest/resources/rest-api-spec/test/painless/50_script_doc_values.yml +++ b/modules/lang-painless/src/yamlRestTest/resources/rest-api-spec/test/painless/50_script_doc_values.yml @@ -81,6 +81,7 @@ setup: boolean: [true, false, true] date: [2017-01-01T12:11:12, 2018-01-01T12:11:12] nanos: [2015-01-01T12:10:30.123456789Z, 2015-01-01T12:10:30.987654321Z] + geo_point: [[-71.34,41.12],[60.32,21.25]] keyword: ["one string", "another string"] long: [1152921504606846976, 576460752303423488] integer: [5, 17, 29] @@ -446,6 +447,66 @@ setup: - match: { hits.hits.0.fields.field.0.lat: 41.1199999647215 } - match: { hits.hits.0.fields.field.0.lon: -71.34000004269183 } + - do: + search: + rest_total_hits_as_int: true + body: + query: { term: { _id: 1 } } + script_fields: + field: + script: + source: "field('geo_point').get(new GeoPoint())" + - match: { hits.hits.0.fields.field.0.lat: 41.1199999647215 } + - match: { hits.hits.0.fields.field.0.lon: -71.34000004269183 } + + - do: + search: + rest_total_hits_as_int: true + body: + query: { term: { _id: 1 } } + script_fields: + field: + script: + source: "/* avoid yaml stash */ $('geo_point', new GeoPoint())" + - match: { hits.hits.0.fields.field.0.lat: 41.1199999647215 } + - match: { hits.hits.0.fields.field.0.lon: -71.34000004269183 } + + - do: + search: + rest_total_hits_as_int: true + body: + query: { term: { _id: 3 } } + script_fields: + field: + script: + source: "field('geo_point').get(new GeoPoint())" + - match: { hits.hits.0.fields.field.0.lat: 21.249999990686774 } + - match: { hits.hits.0.fields.field.0.lon: 60.319999968633056 } + + - do: + search: + rest_total_hits_as_int: true + body: + query: { term: { _id: 3 } } + script_fields: + field: + script: + source: "/* avoid yaml stash */ $('geo_point', new GeoPoint())" + - match: { hits.hits.0.fields.field.0.lat: 21.249999990686774 } + - match: { hits.hits.0.fields.field.0.lon: 60.319999968633056 } + + - do: + search: + rest_total_hits_as_int: true + body: + query: { term: { _id: 3 } } + script_fields: + field: + script: + source: "field('geo_point').get(1, new GeoPoint())" + - match: { hits.hits.0.fields.field.0.lat: 41.1199999647215 } + - match: { hits.hits.0.fields.field.0.lon: -71.34000004269183 } + - do: search: rest_total_hits_as_int: true diff --git a/server/src/main/java/org/elasticsearch/index/fielddata/ScriptDocValues.java b/server/src/main/java/org/elasticsearch/index/fielddata/ScriptDocValues.java index 1ca225e1d8361..b32b728143ea5 100644 --- a/server/src/main/java/org/elasticsearch/index/fielddata/ScriptDocValues.java +++ b/server/src/main/java/org/elasticsearch/index/fielddata/ScriptDocValues.java @@ -287,9 +287,9 @@ public Geometry(Supplier supplier) { public interface GeometrySupplier extends Supplier { - GeoPoint getCentroid(); + GeoPoint getInternalCentroid(); - GeoBoundingBox getBoundingBox(); + GeoBoundingBox getInternalBoundingBox(); } public static class GeoPointsSupplier implements GeometrySupplier { @@ -369,12 +369,12 @@ public GeoPoint getInternal(int index) { } @Override - public GeoPoint getCentroid() { + public GeoPoint getInternalCentroid() { return centroid; } @Override - public GeoBoundingBox getBoundingBox() { + public GeoBoundingBox getInternalBoundingBox() { return boundingBox; } @@ -481,7 +481,7 @@ public int getDimensionalType() { @Override public GeoPoint getCentroid() { - return size() == 0 ? null : geometrySupplier.getCentroid(); + return size() == 0 ? null : geometrySupplier.getInternalCentroid(); } @Override @@ -496,7 +496,7 @@ public double getMercatorHeight() { @Override public GeoBoundingBox getBoundingBox() { - return size() == 0 ? null : geometrySupplier.getBoundingBox(); + return size() == 0 ? null : geometrySupplier.getInternalBoundingBox(); } } diff --git a/server/src/main/java/org/elasticsearch/index/mapper/GeoPointFieldMapper.java b/server/src/main/java/org/elasticsearch/index/mapper/GeoPointFieldMapper.java index e4e5e62f3f9f7..23ed51266b70e 100644 --- a/server/src/main/java/org/elasticsearch/index/mapper/GeoPointFieldMapper.java +++ b/server/src/main/java/org/elasticsearch/index/mapper/GeoPointFieldMapper.java @@ -38,6 +38,7 @@ import org.elasticsearch.script.Script; import org.elasticsearch.script.ScriptCompiler; import org.elasticsearch.script.field.DelegateDocValuesField; +import org.elasticsearch.script.field.GeoPointDocValuesField; import org.elasticsearch.search.aggregations.support.CoreValuesSourceType; import org.elasticsearch.search.lookup.FieldValues; import org.elasticsearch.search.lookup.SearchLookup; @@ -306,11 +307,7 @@ public Query geoShapeQuery(Geometry shape, String fieldName, ShapeRelation relat @Override public IndexFieldData.Builder fielddataBuilder(String fullyQualifiedIndexName, Supplier searchLookup) { failIfNoDocValues(); - return new AbstractLatLonPointIndexFieldData.Builder( - name(), - CoreValuesSourceType.GEOPOINT, - (dv, n) -> new DelegateDocValuesField(new ScriptDocValues.GeoPoints(new ScriptDocValues.GeoPointsSupplier(dv)), n) - ); + return new AbstractLatLonPointIndexFieldData.Builder(name(), CoreValuesSourceType.GEOPOINT, GeoPointDocValuesField::new); } @Override diff --git a/server/src/main/java/org/elasticsearch/script/field/GeoPointDocValuesField.java b/server/src/main/java/org/elasticsearch/script/field/GeoPointDocValuesField.java new file mode 100644 index 0000000000000..84f833d2b5384 --- /dev/null +++ b/server/src/main/java/org/elasticsearch/script/field/GeoPointDocValuesField.java @@ -0,0 +1,164 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +package org.elasticsearch.script.field; + +import org.apache.lucene.util.ArrayUtil; +import org.elasticsearch.common.geo.GeoBoundingBox; +import org.elasticsearch.common.geo.GeoPoint; +import org.elasticsearch.index.fielddata.MultiGeoPointValues; +import org.elasticsearch.index.fielddata.ScriptDocValues; + +import java.io.IOException; +import java.util.Iterator; +import java.util.NoSuchElementException; + +public class GeoPointDocValuesField implements DocValuesField, ScriptDocValues.GeometrySupplier { + + protected final MultiGeoPointValues input; + protected final String name; + + protected GeoPoint[] values = new GeoPoint[0]; + protected int count; + + // maintain bwc by making centroid and bounding box available to ScriptDocValues.GeoPoints + private ScriptDocValues.GeoPoints geoPoints = null; + private final GeoPoint centroid = new GeoPoint(); + private final GeoBoundingBox boundingBox = new GeoBoundingBox(new GeoPoint(), new GeoPoint()); + + public GeoPointDocValuesField(MultiGeoPointValues input, String name) { + this.input = input; + this.name = name; + } + + @Override + public void setNextDocId(int docId) throws IOException { + if (input.advanceExact(docId)) { + resize(input.docValueCount()); + if (count == 1) { + setSingleValue(); + } else { + setMultiValue(); + } + } + } + + private void resize(int newSize) { + count = newSize; + if (newSize > values.length) { + int oldLength = values.length; + values = ArrayUtil.grow(values, count); + for (int i = oldLength; i < values.length; ++i) { + values[i] = new GeoPoint(); + } + } + } + + private void setSingleValue() throws IOException { + GeoPoint point = input.nextValue(); + values[0].reset(point.lat(), point.lon()); + centroid.reset(point.lat(), point.lon()); + boundingBox.topLeft().reset(point.lat(), point.lon()); + boundingBox.bottomRight().reset(point.lat(), point.lon()); + } + + private void setMultiValue() throws IOException { + double centroidLat = 0; + double centroidLon = 0; + double maxLon = Double.NEGATIVE_INFINITY; + double minLon = Double.POSITIVE_INFINITY; + double maxLat = Double.NEGATIVE_INFINITY; + double minLat = Double.POSITIVE_INFINITY; + for (int i = 0; i < count; i++) { + GeoPoint point = input.nextValue(); + values[i].reset(point.lat(), point.lon()); + centroidLat += point.getLat(); + centroidLon += point.getLon(); + maxLon = Math.max(maxLon, values[i].getLon()); + minLon = Math.min(minLon, values[i].getLon()); + maxLat = Math.max(maxLat, values[i].getLat()); + minLat = Math.min(minLat, values[i].getLat()); + } + centroid.reset(centroidLat / count, centroidLon / count); + boundingBox.topLeft().reset(maxLat, minLon); + boundingBox.bottomRight().reset(minLat, maxLon); + } + + @Override + public ScriptDocValues getScriptDocValues() { + if (geoPoints == null) { + geoPoints = new ScriptDocValues.GeoPoints(this); + } + + return geoPoints; + } + + @Override + public GeoPoint getInternal(int index) { + return values[index]; + } + + // maintain bwc by making centroid available to ScriptDocValues.GeoPoints + @Override + public GeoPoint getInternalCentroid() { + return centroid; + } + + // maintain bwc by making bounding box available to ScriptDocValues.GeoPoints + @Override + public GeoBoundingBox getInternalBoundingBox() { + return boundingBox; + } + + @Override + public String getName() { + return name; + } + + @Override + public boolean isEmpty() { + return count == 0; + } + + @Override + public int size() { + return count; + } + + public GeoPoint get(GeoPoint defaultValue) { + return get(0, defaultValue); + } + + public GeoPoint get(int index, GeoPoint defaultValue) { + if (isEmpty() || index < 0 || index >= count) { + return defaultValue; + } + + return values[index]; + } + + @Override + public Iterator iterator() { + return new Iterator() { + private int index = 0; + + @Override + public boolean hasNext() { + return index < count; + } + + @Override + public GeoPoint next() { + if (hasNext() == false) { + throw new NoSuchElementException(); + } + return values[index++]; + } + }; + } +} diff --git a/x-pack/plugin/spatial/src/main/java/org/elasticsearch/xpack/spatial/index/fielddata/plain/AbstractAtomicGeoShapeShapeFieldData.java b/x-pack/plugin/spatial/src/main/java/org/elasticsearch/xpack/spatial/index/fielddata/plain/AbstractAtomicGeoShapeShapeFieldData.java index 7977aba47d691..0c838f383e9c2 100644 --- a/x-pack/plugin/spatial/src/main/java/org/elasticsearch/xpack/spatial/index/fielddata/plain/AbstractAtomicGeoShapeShapeFieldData.java +++ b/x-pack/plugin/spatial/src/main/java/org/elasticsearch/xpack/spatial/index/fielddata/plain/AbstractAtomicGeoShapeShapeFieldData.java @@ -104,12 +104,12 @@ public int size() { } @Override - public GeoPoint getCentroid() { + public GeoPoint getInternalCentroid() { return centroid; } @Override - public GeoBoundingBox getBoundingBox() { + public GeoBoundingBox getInternalBoundingBox() { return boundingBox; } } @@ -130,7 +130,7 @@ public int getDimensionalType() { @Override public GeoPoint getCentroid() { - return gsSupplier.getInternal() == null ? null : gsSupplier.getCentroid(); + return gsSupplier.getInternal() == null ? null : gsSupplier.getInternalCentroid(); } @Override @@ -145,7 +145,7 @@ public double getMercatorHeight() { @Override public GeoBoundingBox getBoundingBox() { - return gsSupplier.getInternal() == null ? null : gsSupplier.getBoundingBox(); + return gsSupplier.getInternal() == null ? null : gsSupplier.getInternalBoundingBox(); } @Override From f0d4b1bf2340621ed79c548e390768d0b7d1a55c Mon Sep 17 00:00:00 2001 From: Jack Conradson Date: Mon, 6 Dec 2021 14:42:25 -0800 Subject: [PATCH 2/7] Update docs/changelog/81395.yaml --- docs/changelog/81395.yaml | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 docs/changelog/81395.yaml diff --git a/docs/changelog/81395.yaml b/docs/changelog/81395.yaml new file mode 100644 index 0000000000000..2e28432460f01 --- /dev/null +++ b/docs/changelog/81395.yaml @@ -0,0 +1,5 @@ +pr: 81395 +summary: Add a geo point field for the scripting fields api +area: Infra/Scripting +type: enhancement +issues: [] From 60bca1211f8416dde342235b9bb6edd6d21ad2ae Mon Sep 17 00:00:00 2001 From: Jack Conradson Date: Mon, 6 Dec 2021 14:43:55 -0800 Subject: [PATCH 3/7] have runtime field user the new GeoPointDocValuesField --- .../index/mapper/GeoPointScriptFieldType.java | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/server/src/main/java/org/elasticsearch/index/mapper/GeoPointScriptFieldType.java b/server/src/main/java/org/elasticsearch/index/mapper/GeoPointScriptFieldType.java index bc89c028c5497..fe1b440cf9578 100644 --- a/server/src/main/java/org/elasticsearch/index/mapper/GeoPointScriptFieldType.java +++ b/server/src/main/java/org/elasticsearch/index/mapper/GeoPointScriptFieldType.java @@ -26,6 +26,7 @@ import org.elasticsearch.script.GeoPointFieldScript; import org.elasticsearch.script.Script; import org.elasticsearch.script.field.DelegateDocValuesField; +import org.elasticsearch.script.field.GeoPointDocValuesField; import org.elasticsearch.search.lookup.SearchLookup; import org.elasticsearch.search.runtime.GeoPointScriptFieldDistanceFeatureQuery; import org.elasticsearch.search.runtime.GeoPointScriptFieldExistsQuery; @@ -98,11 +99,7 @@ public Query termQuery(Object value, SearchExecutionContext context) { @Override public GeoPointScriptFieldData.Builder fielddataBuilder(String fullyQualifiedIndexName, Supplier searchLookup) { - return new GeoPointScriptFieldData.Builder( - name(), - leafFactory(searchLookup.get()), - (dv, n) -> new DelegateDocValuesField(new ScriptDocValues.GeoPoints(new ScriptDocValues.GeoPointsSupplier(dv)), n) - ); + return new GeoPointScriptFieldData.Builder(name(), leafFactory(searchLookup.get()), GeoPointDocValuesField::new); } @Override From 01cd7185157711b8e010da2444a436d90ff1ac67 Mon Sep 17 00:00:00 2001 From: Jack Conradson Date: Tue, 7 Dec 2021 08:56:56 -0800 Subject: [PATCH 4/7] response to pr comments --- .../index/fielddata/ScriptDocValues.java | 92 ------------------- .../index/mapper/GeoPointFieldMapper.java | 2 - .../index/mapper/GeoPointScriptFieldType.java | 2 - .../ScriptDocValuesGeoPointsTests.java | 10 +- 4 files changed, 5 insertions(+), 101 deletions(-) diff --git a/server/src/main/java/org/elasticsearch/index/fielddata/ScriptDocValues.java b/server/src/main/java/org/elasticsearch/index/fielddata/ScriptDocValues.java index b32b728143ea5..095f2ad6cbd0b 100644 --- a/server/src/main/java/org/elasticsearch/index/fielddata/ScriptDocValues.java +++ b/server/src/main/java/org/elasticsearch/index/fielddata/ScriptDocValues.java @@ -292,98 +292,6 @@ public interface GeometrySupplier extends Supplier { GeoBoundingBox getInternalBoundingBox(); } - public static class GeoPointsSupplier implements GeometrySupplier { - - private final MultiGeoPointValues in; - private GeoPoint[] values = new GeoPoint[0]; - private final GeoPoint centroid = new GeoPoint(); - private final GeoBoundingBox boundingBox = new GeoBoundingBox(new GeoPoint(), new GeoPoint()); - private int count; - - public GeoPointsSupplier(MultiGeoPointValues in) { - this.in = in; - } - - @Override - public void setNextDocId(int docId) throws IOException { - if (in.advanceExact(docId)) { - resize(in.docValueCount()); - if (count == 1) { - setSingleValue(); - } else { - setMultiValue(); - } - } else { - resize(0); - } - } - - private void setSingleValue() throws IOException { - GeoPoint point = in.nextValue(); - values[0].reset(point.lat(), point.lon()); - centroid.reset(point.lat(), point.lon()); - boundingBox.topLeft().reset(point.lat(), point.lon()); - boundingBox.bottomRight().reset(point.lat(), point.lon()); - } - - private void setMultiValue() throws IOException { - double centroidLat = 0; - double centroidLon = 0; - double maxLon = Double.NEGATIVE_INFINITY; - double minLon = Double.POSITIVE_INFINITY; - double maxLat = Double.NEGATIVE_INFINITY; - double minLat = Double.POSITIVE_INFINITY; - for (int i = 0; i < count; i++) { - GeoPoint point = in.nextValue(); - values[i].reset(point.lat(), point.lon()); - centroidLat += point.getLat(); - centroidLon += point.getLon(); - maxLon = Math.max(maxLon, values[i].getLon()); - minLon = Math.min(minLon, values[i].getLon()); - maxLat = Math.max(maxLat, values[i].getLat()); - minLat = Math.min(minLat, values[i].getLat()); - } - centroid.reset(centroidLat / count, centroidLon / count); - boundingBox.topLeft().reset(maxLat, minLon); - boundingBox.bottomRight().reset(minLat, maxLon); - } - - /** - * Set the {@link #size()} and ensure that the {@link #values} array can - * store at least that many entries. - */ - private void resize(int newSize) { - count = newSize; - if (newSize > values.length) { - int oldLength = values.length; - values = ArrayUtil.grow(values, count); - for (int i = oldLength; i < values.length; ++i) { - values[i] = new GeoPoint(); - } - } - } - - @Override - public GeoPoint getInternal(int index) { - return values[index]; - } - - @Override - public GeoPoint getInternalCentroid() { - return centroid; - } - - @Override - public GeoBoundingBox getInternalBoundingBox() { - return boundingBox; - } - - @Override - public int size() { - return count; - } - } - public static class GeoPoints extends Geometry { private final GeometrySupplier geometrySupplier; diff --git a/server/src/main/java/org/elasticsearch/index/mapper/GeoPointFieldMapper.java b/server/src/main/java/org/elasticsearch/index/mapper/GeoPointFieldMapper.java index 23ed51266b70e..f6e358de4e8f4 100644 --- a/server/src/main/java/org/elasticsearch/index/mapper/GeoPointFieldMapper.java +++ b/server/src/main/java/org/elasticsearch/index/mapper/GeoPointFieldMapper.java @@ -31,13 +31,11 @@ import org.elasticsearch.geometry.Point; import org.elasticsearch.geometry.ShapeType; import org.elasticsearch.index.fielddata.IndexFieldData; -import org.elasticsearch.index.fielddata.ScriptDocValues; import org.elasticsearch.index.fielddata.plain.AbstractLatLonPointIndexFieldData; import org.elasticsearch.index.query.SearchExecutionContext; import org.elasticsearch.script.GeoPointFieldScript; import org.elasticsearch.script.Script; import org.elasticsearch.script.ScriptCompiler; -import org.elasticsearch.script.field.DelegateDocValuesField; import org.elasticsearch.script.field.GeoPointDocValuesField; import org.elasticsearch.search.aggregations.support.CoreValuesSourceType; import org.elasticsearch.search.lookup.FieldValues; diff --git a/server/src/main/java/org/elasticsearch/index/mapper/GeoPointScriptFieldType.java b/server/src/main/java/org/elasticsearch/index/mapper/GeoPointScriptFieldType.java index fe1b440cf9578..0154817048d33 100644 --- a/server/src/main/java/org/elasticsearch/index/mapper/GeoPointScriptFieldType.java +++ b/server/src/main/java/org/elasticsearch/index/mapper/GeoPointScriptFieldType.java @@ -20,12 +20,10 @@ import org.elasticsearch.common.unit.DistanceUnit; import org.elasticsearch.geometry.Geometry; import org.elasticsearch.index.fielddata.GeoPointScriptFieldData; -import org.elasticsearch.index.fielddata.ScriptDocValues; import org.elasticsearch.index.query.SearchExecutionContext; import org.elasticsearch.script.CompositeFieldScript; import org.elasticsearch.script.GeoPointFieldScript; import org.elasticsearch.script.Script; -import org.elasticsearch.script.field.DelegateDocValuesField; import org.elasticsearch.script.field.GeoPointDocValuesField; import org.elasticsearch.search.lookup.SearchLookup; import org.elasticsearch.search.runtime.GeoPointScriptFieldDistanceFeatureQuery; diff --git a/server/src/test/java/org/elasticsearch/index/fielddata/ScriptDocValuesGeoPointsTests.java b/server/src/test/java/org/elasticsearch/index/fielddata/ScriptDocValuesGeoPointsTests.java index 3d15faa3146bd..980e8b12eaa87 100644 --- a/server/src/test/java/org/elasticsearch/index/fielddata/ScriptDocValuesGeoPointsTests.java +++ b/server/src/test/java/org/elasticsearch/index/fielddata/ScriptDocValuesGeoPointsTests.java @@ -11,7 +11,7 @@ import org.elasticsearch.common.geo.GeoPoint; import org.elasticsearch.common.geo.GeoUtils; import org.elasticsearch.index.fielddata.ScriptDocValues.GeoPoints; -import org.elasticsearch.index.fielddata.ScriptDocValues.GeoPointsSupplier; +import org.elasticsearch.script.field.GeoPointDocValuesField; import org.elasticsearch.test.ESTestCase; import java.io.IOException; @@ -63,7 +63,7 @@ public void testGeoGetLatLon() throws IOException { GeoPoint[][] points = { { new GeoPoint(lat1, lon1), new GeoPoint(lat2, lon2) } }; final MultiGeoPointValues values = wrap(points); - final ScriptDocValues.GeoPoints script = new ScriptDocValues.GeoPoints(new GeoPointsSupplier(values)); + final ScriptDocValues.GeoPoints script = (GeoPoints)new GeoPointDocValuesField(values, "test").getScriptDocValues(); script.getSupplier().setNextDocId(1); assertEquals(true, script.isEmpty()); @@ -81,11 +81,11 @@ public void testGeoDistance() throws IOException { final double lon = randomLon(); GeoPoint[][] points = { { new GeoPoint(lat, lon) } }; final MultiGeoPointValues values = wrap(points); - final ScriptDocValues.GeoPoints script = new ScriptDocValues.GeoPoints(new GeoPointsSupplier(values)); + final ScriptDocValues.GeoPoints script = (GeoPoints)new GeoPointDocValuesField(values, "test").getScriptDocValues(); script.getSupplier().setNextDocId(0); GeoPoint[][] points2 = { new GeoPoint[0] }; - final ScriptDocValues.GeoPoints emptyScript = new ScriptDocValues.GeoPoints(new GeoPointsSupplier(wrap(points2))); + final ScriptDocValues.GeoPoints emptyScript = (GeoPoints)new GeoPointDocValuesField(wrap(points2), "test").getScriptDocValues(); emptyScript.getSupplier().setNextDocId(0); final double otherLat = randomLat(); @@ -116,7 +116,7 @@ public void testMissingValues() throws IOException { points[d][i] = new GeoPoint(randomLat(), randomLon()); } } - final ScriptDocValues.GeoPoints geoPoints = new GeoPoints(new GeoPointsSupplier(wrap(points))); + final ScriptDocValues.GeoPoints geoPoints = (GeoPoints)new GeoPointDocValuesField(wrap(points), "test").getScriptDocValues(); for (int d = 0; d < points.length; d++) { geoPoints.getSupplier().setNextDocId(d); if (points[d].length > 0) { From 359eff0b60457a2fdfa3acd3dac8481f37a10708 Mon Sep 17 00:00:00 2001 From: Jack Conradson Date: Tue, 7 Dec 2021 10:02:43 -0800 Subject: [PATCH 5/7] spotless --- .../index/fielddata/ScriptDocValuesGeoPointsTests.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/server/src/test/java/org/elasticsearch/index/fielddata/ScriptDocValuesGeoPointsTests.java b/server/src/test/java/org/elasticsearch/index/fielddata/ScriptDocValuesGeoPointsTests.java index 980e8b12eaa87..55e6d3046d973 100644 --- a/server/src/test/java/org/elasticsearch/index/fielddata/ScriptDocValuesGeoPointsTests.java +++ b/server/src/test/java/org/elasticsearch/index/fielddata/ScriptDocValuesGeoPointsTests.java @@ -63,7 +63,7 @@ public void testGeoGetLatLon() throws IOException { GeoPoint[][] points = { { new GeoPoint(lat1, lon1), new GeoPoint(lat2, lon2) } }; final MultiGeoPointValues values = wrap(points); - final ScriptDocValues.GeoPoints script = (GeoPoints)new GeoPointDocValuesField(values, "test").getScriptDocValues(); + final ScriptDocValues.GeoPoints script = (GeoPoints) new GeoPointDocValuesField(values, "test").getScriptDocValues(); script.getSupplier().setNextDocId(1); assertEquals(true, script.isEmpty()); @@ -81,11 +81,11 @@ public void testGeoDistance() throws IOException { final double lon = randomLon(); GeoPoint[][] points = { { new GeoPoint(lat, lon) } }; final MultiGeoPointValues values = wrap(points); - final ScriptDocValues.GeoPoints script = (GeoPoints)new GeoPointDocValuesField(values, "test").getScriptDocValues(); + final ScriptDocValues.GeoPoints script = (GeoPoints) new GeoPointDocValuesField(values, "test").getScriptDocValues(); script.getSupplier().setNextDocId(0); GeoPoint[][] points2 = { new GeoPoint[0] }; - final ScriptDocValues.GeoPoints emptyScript = (GeoPoints)new GeoPointDocValuesField(wrap(points2), "test").getScriptDocValues(); + final ScriptDocValues.GeoPoints emptyScript = (GeoPoints) new GeoPointDocValuesField(wrap(points2), "test").getScriptDocValues(); emptyScript.getSupplier().setNextDocId(0); final double otherLat = randomLat(); @@ -116,7 +116,7 @@ public void testMissingValues() throws IOException { points[d][i] = new GeoPoint(randomLat(), randomLon()); } } - final ScriptDocValues.GeoPoints geoPoints = (GeoPoints)new GeoPointDocValuesField(wrap(points), "test").getScriptDocValues(); + final ScriptDocValues.GeoPoints geoPoints = (GeoPoints) new GeoPointDocValuesField(wrap(points), "test").getScriptDocValues(); for (int d = 0; d < points.length; d++) { geoPoints.getSupplier().setNextDocId(d); if (points[d].length > 0) { From 514eb0b534c3ab9046c5801acea9e2ee8f8887fa Mon Sep 17 00:00:00 2001 From: Jack Conradson Date: Tue, 7 Dec 2021 10:21:57 -0800 Subject: [PATCH 6/7] fix test --- .../org/elasticsearch/script/field/GeoPointDocValuesField.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/server/src/main/java/org/elasticsearch/script/field/GeoPointDocValuesField.java b/server/src/main/java/org/elasticsearch/script/field/GeoPointDocValuesField.java index 84f833d2b5384..b4d7f724fe580 100644 --- a/server/src/main/java/org/elasticsearch/script/field/GeoPointDocValuesField.java +++ b/server/src/main/java/org/elasticsearch/script/field/GeoPointDocValuesField.java @@ -45,6 +45,8 @@ public void setNextDocId(int docId) throws IOException { } else { setMultiValue(); } + } else { + resize(0); } } From d99a67f051fa2839c84006befd91c1dc9e234de8 Mon Sep 17 00:00:00 2001 From: Jack Conradson Date: Tue, 7 Dec 2021 10:34:42 -0800 Subject: [PATCH 7/7] add test for non-default geo point constructor --- .../test/painless/50_script_doc_values.yml | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/modules/lang-painless/src/yamlRestTest/resources/rest-api-spec/test/painless/50_script_doc_values.yml b/modules/lang-painless/src/yamlRestTest/resources/rest-api-spec/test/painless/50_script_doc_values.yml index 760b041054f6a..7adb2c87e6541 100644 --- a/modules/lang-painless/src/yamlRestTest/resources/rest-api-spec/test/painless/50_script_doc_values.yml +++ b/modules/lang-painless/src/yamlRestTest/resources/rest-api-spec/test/painless/50_script_doc_values.yml @@ -508,6 +508,18 @@ setup: - match: { hits.hits.0.fields.field.0.lat: 41.1199999647215 } - match: { hits.hits.0.fields.field.0.lon: -71.34000004269183 } + - do: + search: + rest_total_hits_as_int: true + body: + query: { term: { _id: 2 } } + script_fields: + field: + script: + source: "/* avoid yaml stash */ $('geo_point', new GeoPoint(1.0, 2.0))" + - match: { hits.hits.0.fields.field.0.lat: 1.0 } + - match: { hits.hits.0.fields.field.0.lon: 2.0 } + - do: search: rest_total_hits_as_int: true