Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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