Skip to content

Commit

Permalink
Add a geo point field for the scripting fields api (#81395)
Browse files Browse the repository at this point in the history
This adds a geo point(s) field for the scripting fields api. This field only supports get(default), 
get(index, default), and iterator right now. This also adds the ability to create new a GeoPoint through 
the allow list, so users can specify a default that makes sense. It does not include reset as this field 
currently does not wrap the data to be read-only.
  • Loading branch information
jdconrad authored Dec 7, 2021
1 parent 8a612d6 commit d59038b
Show file tree
Hide file tree
Showing 10 changed files with 268 additions and 119 deletions.
5 changes: 5 additions & 0 deletions docs/changelog/81395.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
pr: 81395
summary: Add a geo point field for the scripting fields api
area: Infra/Scripting
type: enhancement
issues: []
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,11 @@ class org.elasticsearch.script.field.KeywordDocValuesField @dynamic_type {
String get(int, String)
}

class org.elasticsearch.script.field.GeoPointDocValuesField @dynamic_type {
GeoPoint get(GeoPoint)
GeoPoint get(int, GeoPoint)
}

class org.elasticsearch.script.field.IpDocValuesField @dynamic_type {
IPAddress get(IPAddress)
IPAddress get(int, IPAddress)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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()
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,7 @@ setup:
ip: ["10.1.2.3", "2001:db8::2:1"]
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]
Expand Down Expand Up @@ -447,6 +448,78 @@ 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
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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -287,101 +287,9 @@ public Geometry(Supplier<T> supplier) {

public interface GeometrySupplier<T> extends Supplier<T> {

GeoPoint getCentroid();
GeoPoint getInternalCentroid();

GeoBoundingBox getBoundingBox();
}

public static class GeoPointsSupplier implements GeometrySupplier<GeoPoint> {

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 getCentroid() {
return centroid;
}

@Override
public GeoBoundingBox getBoundingBox() {
return boundingBox;
}

@Override
public int size() {
return count;
}
GeoBoundingBox getInternalBoundingBox();
}

public static class GeoPoints extends Geometry<GeoPoint> {
Expand Down Expand Up @@ -481,7 +389,7 @@ public int getDimensionalType() {

@Override
public GeoPoint getCentroid() {
return size() == 0 ? null : geometrySupplier.getCentroid();
return size() == 0 ? null : geometrySupplier.getInternalCentroid();
}

@Override
Expand All @@ -496,7 +404,7 @@ public double getMercatorHeight() {

@Override
public GeoBoundingBox getBoundingBox() {
return size() == 0 ? null : geometrySupplier.getBoundingBox();
return size() == 0 ? null : geometrySupplier.getInternalBoundingBox();
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,13 +31,12 @@
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;
import org.elasticsearch.search.lookup.SearchLookup;
Expand Down Expand Up @@ -306,11 +305,7 @@ public Query geoShapeQuery(Geometry shape, String fieldName, ShapeRelation relat
@Override
public IndexFieldData.Builder fielddataBuilder(String fullyQualifiedIndexName, Supplier<SearchLookup> 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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,12 +20,11 @@
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;
import org.elasticsearch.search.runtime.GeoPointScriptFieldExistsQuery;
Expand Down Expand Up @@ -98,11 +97,7 @@ public Query termQuery(Object value, SearchExecutionContext context) {

@Override
public GeoPointScriptFieldData.Builder fielddataBuilder(String fullyQualifiedIndexName, Supplier<SearchLookup> 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
Expand Down
Loading

0 comments on commit d59038b

Please sign in to comment.