diff --git a/modules/benchmark/micro/src/main/java/org/elasticsearch/benchmark/search/geo/GeoDistanceSearchBenchmark.java b/modules/benchmark/micro/src/main/java/org/elasticsearch/benchmark/search/geo/GeoDistanceSearchBenchmark.java new file mode 100644 index 00000000000..156d9be73b9 --- /dev/null +++ b/modules/benchmark/micro/src/main/java/org/elasticsearch/benchmark/search/geo/GeoDistanceSearchBenchmark.java @@ -0,0 +1,151 @@ +/* + * Licensed to Elastic Search and Shay Banon under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. Elastic Search licenses this + * file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.elasticsearch.benchmark.search.geo; + +import org.elasticsearch.action.admin.cluster.health.ClusterHealthResponse; +import org.elasticsearch.action.search.SearchType; +import org.elasticsearch.client.Client; +import org.elasticsearch.common.settings.ImmutableSettings; +import org.elasticsearch.common.unit.SizeValue; +import org.elasticsearch.common.xcontent.XContentFactory; +import org.elasticsearch.index.query.QueryBuilders; +import org.elasticsearch.index.search.geo.GeoDistance; +import org.elasticsearch.node.Node; +import org.elasticsearch.node.NodeBuilder; + +import static org.elasticsearch.common.xcontent.XContentFactory.*; +import static org.elasticsearch.index.query.FilterBuilders.*; +import static org.elasticsearch.index.query.QueryBuilders.*; + +/** + */ +public class GeoDistanceSearchBenchmark { + + public static void main(String[] args) throws Exception { + + Node node = NodeBuilder.nodeBuilder().node(); + Client client = node.client(); + + ClusterHealthResponse clusterHealthResponse = client.admin().cluster().prepareHealth().setWaitForGreenStatus().execute().actionGet(); + if (clusterHealthResponse.timedOut()) { + System.err.println("Failed to wait for green status, bailing"); + System.exit(1); + } + + final long NUM_DOCS = SizeValue.parseSizeValue("1m").singles(); + final long NUM_WARM = 50; + final long NUM_RUNS = 100; + + if (client.admin().indices().prepareExists("test").execute().actionGet().exists()) { + System.out.println("Found an index, count: " + client.prepareCount("test").setQuery(QueryBuilders.matchAllQuery()).execute().actionGet().count()); + } else { + String mapping = XContentFactory.jsonBuilder().startObject().startObject("type1") + .startObject("properties").startObject("location").field("type", "geo_point").field("lat_lon", true).endObject().endObject() + .endObject().endObject().string(); + client.admin().indices().prepareCreate("test") + .setSettings(ImmutableSettings.settingsBuilder().put("number_of_shards", 1).put("number_of_replicas", 0)) + .addMapping("type1", mapping) + .execute().actionGet(); + + System.err.println("--> Indexing [" + NUM_DOCS + "]"); + for (long i = 0; i < NUM_DOCS; ) { + client.prepareIndex("test", "type1", Long.toString(i++)).setSource(jsonBuilder().startObject() + .field("name", "New York") + .startObject("location").field("lat", 40.7143528).field("lon", -74.0059731).endObject() + .endObject()).execute().actionGet(); + + // to NY: 5.286 km + client.prepareIndex("test", "type1", Long.toString(i++)).setSource(jsonBuilder().startObject() + .field("name", "Times Square") + .startObject("location").field("lat", 40.759011).field("lon", -73.9844722).endObject() + .endObject()).execute().actionGet(); + + // to NY: 0.4621 km + client.prepareIndex("test", "type1", Long.toString(i++)).setSource(jsonBuilder().startObject() + .field("name", "Tribeca") + .startObject("location").field("lat", 40.718266).field("lon", -74.007819).endObject() + .endObject()).execute().actionGet(); + + // to NY: 1.258 km + client.prepareIndex("test", "type1", Long.toString(i++)).setSource(jsonBuilder().startObject() + .field("name", "Soho") + .startObject("location").field("lat", 40.7247222).field("lon", -74).endObject() + .endObject()).execute().actionGet(); + + // to NY: 8.572 km + client.prepareIndex("test", "type1", Long.toString(i++)).setSource(jsonBuilder().startObject() + .field("name", "Brooklyn") + .startObject("location").field("lat", 40.65).field("lon", -73.95).endObject() + .endObject()).execute().actionGet(); + + if ((i % 10000) == 0) { + System.err.println("--> indexed " + i); + } + } + System.err.println("Done indexed"); + client.admin().indices().prepareFlush("test").execute().actionGet(); + client.admin().indices().prepareRefresh().execute().actionGet(); + } + + System.err.println("--> Warming up (ARC)"); + long start = System.currentTimeMillis(); + for (int i = 0; i < NUM_WARM; i++) { + run(client, GeoDistance.ARC); + } + long totalTime = System.currentTimeMillis() - start; + System.out.println("--> Warmup (ARC) " + (totalTime / NUM_WARM) + "ms"); + + System.err.println("--> Perf (ARC)"); + start = System.currentTimeMillis(); + for (int i = 0; i < NUM_RUNS; i++) { + run(client, GeoDistance.ARC); + } + totalTime = System.currentTimeMillis() - start; + System.out.println("--> Perf (ARC) " + (totalTime / NUM_RUNS) + "ms"); + + System.err.println("--> Warming up (PLANE)"); + start = System.currentTimeMillis(); + for (int i = 0; i < NUM_WARM; i++) { + run(client, GeoDistance.PLANE); + } + totalTime = System.currentTimeMillis() - start; + System.out.println("--> Warmup (PLANE) " + (totalTime / NUM_WARM) + "ms"); + + System.err.println("--> Perf (PLANE)"); + start = System.currentTimeMillis(); + for (int i = 0; i < NUM_RUNS; i++) { + run(client, GeoDistance.PLANE); + } + totalTime = System.currentTimeMillis() - start; + System.out.println("--> Perf (PLANE) " + (totalTime / NUM_RUNS) + "ms"); + + node.close(); + } + + public static void run(Client client, GeoDistance geoDistance) { + client.prepareSearch() // from NY + .setSearchType(SearchType.COUNT) + .setQuery(filteredQuery(matchAllQuery(), geoDistanceFilter("location") + .distance("2km") + .geoDistance(geoDistance) + .point(40.7143528, -74.0059731))) + .execute().actionGet(); + } +} diff --git a/modules/elasticsearch/src/main/java/org/elasticsearch/index/search/geo/GeoDistance.java b/modules/elasticsearch/src/main/java/org/elasticsearch/index/search/geo/GeoDistance.java index e5bd18fde95..760ae078ba6 100644 --- a/modules/elasticsearch/src/main/java/org/elasticsearch/index/search/geo/GeoDistance.java +++ b/modules/elasticsearch/src/main/java/org/elasticsearch/index/search/geo/GeoDistance.java @@ -41,6 +41,10 @@ public enum GeoDistance { @Override public double normalize(double distance, DistanceUnit unit) { return distance; } + + @Override public FixedSourceDistance fixedSourceDistance(double sourceLatitude, double sourceLongitude, DistanceUnit unit) { + return new PlaneFixedSourceDistance(sourceLatitude, sourceLongitude, unit); + } }, /** * Calculates distance factor. @@ -57,6 +61,10 @@ public enum GeoDistance { @Override public double normalize(double distance, DistanceUnit unit) { return Math.cos(distance / unit.getEarthRadius()); } + + @Override public FixedSourceDistance fixedSourceDistance(double sourceLatitude, double sourceLongitude, DistanceUnit unit) { + return new FactorFixedSourceDistance(sourceLatitude, sourceLongitude, unit); + } }, /** * Calculates distance as points in a globe. @@ -81,12 +89,18 @@ public enum GeoDistance { @Override public double normalize(double distance, DistanceUnit unit) { return distance; } + + @Override public FixedSourceDistance fixedSourceDistance(double sourceLatitude, double sourceLongitude, DistanceUnit unit) { + return new ArcFixedSourceDistance(sourceLatitude, sourceLongitude, unit); + } }; public abstract double normalize(double distance, DistanceUnit unit); public abstract double calculate(double sourceLatitude, double sourceLongitude, double targetLatitude, double targetLongitude, DistanceUnit unit); + public abstract FixedSourceDistance fixedSourceDistance(double sourceLatitude, double sourceLongitude, DistanceUnit unit); + public static GeoDistance fromString(String s) { if ("plane".equals(s)) { return PLANE; @@ -97,4 +111,91 @@ public enum GeoDistance { } throw new ElasticSearchIllegalArgumentException("No geo distance for [" + s + "]"); } + + public static interface FixedSourceDistance { + + double calculate(double targetLatitude, double targetLongitude); + } + + public static class PlaneFixedSourceDistance implements FixedSourceDistance { + + private final double sourceLatitude; + private final double sourceLongitude; + private final double distancePerDegree; + + public PlaneFixedSourceDistance(double sourceLatitude, double sourceLongitude, DistanceUnit unit) { + this.sourceLatitude = sourceLatitude; + this.sourceLongitude = sourceLongitude; + this.distancePerDegree = unit.getDistancePerDegree(); + } + + @Override public double calculate(double targetLatitude, double targetLongitude) { + double px = targetLongitude - sourceLongitude; + double py = targetLatitude - sourceLatitude; + return Math.sqrt(px * px + py * py) * distancePerDegree; + } + } + + public static class FactorFixedSourceDistance implements FixedSourceDistance { + + private final double sourceLatitude; + private final double sourceLongitude; + private final double earthRadius; + + private final double a; + private final double sinA; + private final double cosA; + + public FactorFixedSourceDistance(double sourceLatitude, double sourceLongitude, DistanceUnit unit) { + this.sourceLatitude = sourceLatitude; + this.sourceLongitude = sourceLongitude; + this.earthRadius = unit.getEarthRadius(); + this.a = Math.toRadians(90D - sourceLatitude); + this.sinA = Math.sin(a); + this.cosA = Math.cos(a); + } + + @Override public double calculate(double targetLatitude, double targetLongitude) { + // TODO: we might want to normalize longitude as we did in LatLng... + double longitudeDifference = targetLongitude - sourceLongitude; + double c = Math.toRadians(90D - targetLatitude); + return (cosA * Math.cos(c)) + (sinA * Math.sin(c) * Math.cos(Math.toRadians(longitudeDifference))); + } + } + + + public static class ArcFixedSourceDistance implements FixedSourceDistance { + + private final double sourceLatitude; + private final double sourceLongitude; + private final double earthRadius; + + private final double a; + private final double sinA; + private final double cosA; + + public ArcFixedSourceDistance(double sourceLatitude, double sourceLongitude, DistanceUnit unit) { + this.sourceLatitude = sourceLatitude; + this.sourceLongitude = sourceLongitude; + this.earthRadius = unit.getEarthRadius(); + this.a = Math.toRadians(90D - sourceLatitude); + this.sinA = Math.sin(a); + this.cosA = Math.cos(a); + } + + @Override public double calculate(double targetLatitude, double targetLongitude) { + // TODO: we might want to normalize longitude as we did in LatLng... + double longitudeDifference = targetLongitude - sourceLongitude; + double c = Math.toRadians(90D - targetLatitude); + double factor = (cosA * Math.cos(c)) + (sinA * Math.sin(c) * Math.cos(Math.toRadians(longitudeDifference))); + + if (factor < -1D) { + return Math.PI * earthRadius; + } else if (factor >= 1D) { + return 0; + } else { + return Math.acos(factor) * earthRadius; + } + } + } } diff --git a/modules/elasticsearch/src/main/java/org/elasticsearch/index/search/geo/GeoDistanceDataComparator.java b/modules/elasticsearch/src/main/java/org/elasticsearch/index/search/geo/GeoDistanceDataComparator.java index 4cefd6335c8..3b55fbec45d 100644 --- a/modules/elasticsearch/src/main/java/org/elasticsearch/index/search/geo/GeoDistanceDataComparator.java +++ b/modules/elasticsearch/src/main/java/org/elasticsearch/index/search/geo/GeoDistanceDataComparator.java @@ -91,6 +91,7 @@ public class GeoDistanceDataComparator extends FieldComparator { protected final DistanceUnit unit; protected final GeoDistance geoDistance; + protected final GeoDistance.FixedSourceDistance fixedSourceDistance; protected final FieldDataCache fieldDataCache; @@ -111,6 +112,8 @@ public class GeoDistanceDataComparator extends FieldComparator { this.geoDistance = geoDistance; this.fieldDataCache = fieldDataCache; + this.fixedSourceDistance = geoDistance.fixedSourceDistance(lat, lon, unit); + FieldMapper mapper = mapperService.smartNameFieldMapper(fieldName); if (mapper == null) { throw new ElasticSearchIllegalArgumentException("No mapping found for field [" + fieldName + "] for geo distance sort"); @@ -143,7 +146,7 @@ public class GeoDistanceDataComparator extends FieldComparator { // is this true? push this to the "end" distance = Double.MAX_VALUE; } else { - distance = geoDistance.calculate(lat, lon, fieldData.latValue(doc), fieldData.lonValue(doc), unit); + distance = fixedSourceDistance.calculate(fieldData.latValue(doc), fieldData.lonValue(doc)); } final double v2 = distance; if (bottom > v2) { @@ -161,7 +164,7 @@ public class GeoDistanceDataComparator extends FieldComparator { // is this true? push this to the "end" distance = Double.MAX_VALUE; } else { - distance = geoDistance.calculate(lat, lon, fieldData.latValue(doc), fieldData.lonValue(doc), unit); + distance = fixedSourceDistance.calculate(fieldData.latValue(doc), fieldData.lonValue(doc)); } values[slot] = distance; } diff --git a/modules/elasticsearch/src/main/java/org/elasticsearch/index/search/geo/GeoDistanceFilter.java b/modules/elasticsearch/src/main/java/org/elasticsearch/index/search/geo/GeoDistanceFilter.java index fc45043db5f..55893b46460 100644 --- a/modules/elasticsearch/src/main/java/org/elasticsearch/index/search/geo/GeoDistanceFilter.java +++ b/modules/elasticsearch/src/main/java/org/elasticsearch/index/search/geo/GeoDistanceFilter.java @@ -47,6 +47,8 @@ public class GeoDistanceFilter extends Filter { private final FieldDataCache fieldDataCache; + private final GeoDistance.FixedSourceDistance fixedSourceDistance; + public GeoDistanceFilter(double lat, double lon, double distance, GeoDistance geoDistance, String fieldName, FieldDataCache fieldDataCache) { this.lat = lat; this.lon = lon; @@ -54,6 +56,8 @@ public class GeoDistanceFilter extends Filter { this.geoDistance = geoDistance; this.fieldName = fieldName; this.fieldDataCache = fieldDataCache; + + this.fixedSourceDistance = geoDistance.fixedSourceDistance(lat, lon, DistanceUnit.MILES); } public double lat() { @@ -78,7 +82,7 @@ public class GeoDistanceFilter extends Filter { @Override public DocIdSet getDocIdSet(IndexReader reader) throws IOException { final GeoPointFieldData fieldData = (GeoPointFieldData) fieldDataCache.cache(GeoPointFieldDataType.TYPE, reader, fieldName); - return new GeoDistanceDocSet(reader.maxDoc(), geoDistance, fieldData, lat, lon, distance); + return new GeoDistanceDocSet(reader.maxDoc(), fieldData, fixedSourceDistance, distance); } @Override @@ -113,18 +117,14 @@ public class GeoDistanceFilter extends Filter { } public static class GeoDistanceDocSet extends GetDocSet { - private final GeoDistance geoDistance; + private final double distance; // in miles private final GeoPointFieldData fieldData; - private final double lat; - private final double lon; - private final double distance; + private final GeoDistance.FixedSourceDistance fixedSourceDistance; - public GeoDistanceDocSet(int maxDoc, GeoDistance geoDistance, GeoPointFieldData fieldData, double lat, double lon, double distance) { + public GeoDistanceDocSet(int maxDoc, GeoPointFieldData fieldData, GeoDistance.FixedSourceDistance fixedSourceDistance, double distance) { super(maxDoc); - this.geoDistance = geoDistance; this.fieldData = fieldData; - this.lat = lat; - this.lon = lon; + this.fixedSourceDistance = fixedSourceDistance; this.distance = distance; } @@ -144,14 +144,14 @@ public class GeoDistanceFilter extends Filter { double[] lats = fieldData.latValues(doc); double[] lons = fieldData.lonValues(doc); for (int i = 0; i < lats.length; i++) { - double d = geoDistance.calculate(lat, lon, lats[i], lons[i], DistanceUnit.MILES); + double d = fixedSourceDistance.calculate(lats[i], lons[i]); if (d < distance) { return true; } } return false; } else { - double d = geoDistance.calculate(lat, lon, fieldData.latValue(doc), fieldData.lonValue(doc), DistanceUnit.MILES); + double d = fixedSourceDistance.calculate(fieldData.latValue(doc), fieldData.lonValue(doc)); return d < distance; } } diff --git a/modules/elasticsearch/src/main/java/org/elasticsearch/index/search/geo/GeoDistanceRangeFilter.java b/modules/elasticsearch/src/main/java/org/elasticsearch/index/search/geo/GeoDistanceRangeFilter.java index dbf35de5290..3f268dee836 100644 --- a/modules/elasticsearch/src/main/java/org/elasticsearch/index/search/geo/GeoDistanceRangeFilter.java +++ b/modules/elasticsearch/src/main/java/org/elasticsearch/index/search/geo/GeoDistanceRangeFilter.java @@ -43,6 +43,7 @@ public class GeoDistanceRangeFilter extends Filter { private final double inclusiveUpperPoint; // in miles private final GeoDistance geoDistance; + private final GeoDistance.FixedSourceDistance fixedSourceDistance; private final String fieldName; @@ -55,6 +56,8 @@ public class GeoDistanceRangeFilter extends Filter { this.fieldName = fieldName; this.fieldDataCache = fieldDataCache; + this.fixedSourceDistance = geoDistance.fixedSourceDistance(lat, lon, DistanceUnit.MILES); + if (lowerVal != null) { double f = lowerVal.doubleValue(); long i = NumericUtils.doubleToSortableLong(f); @@ -89,7 +92,7 @@ public class GeoDistanceRangeFilter extends Filter { @Override public DocIdSet getDocIdSet(IndexReader reader) throws IOException { final GeoPointFieldData fieldData = (GeoPointFieldData) fieldDataCache.cache(GeoPointFieldDataType.TYPE, reader, fieldName); - return new GeoDistanceRangeDocSet(reader.maxDoc(), fieldData, geoDistance, lat, lon, inclusiveLowerPoint, inclusiveUpperPoint); + return new GeoDistanceRangeDocSet(reader.maxDoc(), fieldData, fixedSourceDistance, inclusiveLowerPoint, inclusiveUpperPoint); } @Override @@ -129,18 +132,14 @@ public class GeoDistanceRangeFilter extends Filter { public static class GeoDistanceRangeDocSet extends GetDocSet { private final GeoPointFieldData fieldData; - private final GeoDistance geoDistance; - private final double lat; - private final double lon; + private final GeoDistance.FixedSourceDistance fixedSourceDistance; private final double inclusiveLowerPoint; // in miles private final double inclusiveUpperPoint; // in miles - public GeoDistanceRangeDocSet(int maxDoc, GeoPointFieldData fieldData, GeoDistance geoDistance, double lat, double lon, double inclusiveLowerPoint, double inclusiveUpperPoint) { + public GeoDistanceRangeDocSet(int maxDoc, GeoPointFieldData fieldData, GeoDistance.FixedSourceDistance fixedSourceDistance, double inclusiveLowerPoint, double inclusiveUpperPoint) { super(maxDoc); this.fieldData = fieldData; - this.geoDistance = geoDistance; - this.lat = lat; - this.lon = lon; + this.fixedSourceDistance = fixedSourceDistance; this.inclusiveLowerPoint = inclusiveLowerPoint; this.inclusiveUpperPoint = inclusiveUpperPoint; } @@ -161,14 +160,14 @@ public class GeoDistanceRangeFilter extends Filter { double[] lats = fieldData.latValues(doc); double[] lons = fieldData.lonValues(doc); for (int i = 0; i < lats.length; i++) { - double d = geoDistance.calculate(lat, lon, lats[i], lons[i], DistanceUnit.MILES); + double d = fixedSourceDistance.calculate(lats[i], lons[i]); if (d >= inclusiveLowerPoint && d <= inclusiveUpperPoint) { return true; } } return false; } else { - double d = geoDistance.calculate(lat, lon, fieldData.latValue(doc), fieldData.lonValue(doc), DistanceUnit.MILES); + double d = fixedSourceDistance.calculate(fieldData.latValue(doc), fieldData.lonValue(doc)); if (d >= inclusiveLowerPoint && d <= inclusiveUpperPoint) { return true; } diff --git a/modules/elasticsearch/src/main/java/org/elasticsearch/search/facet/geodistance/GeoDistanceFacetCollector.java b/modules/elasticsearch/src/main/java/org/elasticsearch/search/facet/geodistance/GeoDistanceFacetCollector.java index 72fd1230208..a470dfe7d80 100644 --- a/modules/elasticsearch/src/main/java/org/elasticsearch/search/facet/geodistance/GeoDistanceFacetCollector.java +++ b/modules/elasticsearch/src/main/java/org/elasticsearch/search/facet/geodistance/GeoDistanceFacetCollector.java @@ -47,6 +47,7 @@ public class GeoDistanceFacetCollector extends AbstractFacetCollector { protected final DistanceUnit unit; protected final GeoDistance geoDistance; + protected final GeoDistance.FixedSourceDistance fixedSourceDistance; protected final FieldDataCache fieldDataCache; @@ -66,6 +67,8 @@ public class GeoDistanceFacetCollector extends AbstractFacetCollector { this.geoDistance = geoDistance; this.fieldDataCache = context.fieldDataCache(); + this.fixedSourceDistance = geoDistance.fixedSourceDistance(lat, lon, unit); + MapperService.SmartNameFieldMappers smartMappers = context.mapperService().smartName(fieldName); if (smartMappers == null || !smartMappers.hasMapper()) { throw new FacetPhaseExecutionException(facetName, "No mapping found for field [" + fieldName + "]"); @@ -80,7 +83,7 @@ public class GeoDistanceFacetCollector extends AbstractFacetCollector { } this.indexFieldName = smartMappers.mapper().names().indexName(); - this.aggregator = new Aggregator(lat, lon, geoDistance, unit, entries); + this.aggregator = new Aggregator(fixedSourceDistance, entries); } @Override protected void doSetNextReader(IndexReader reader, int docBase) throws IOException { @@ -100,26 +103,17 @@ public class GeoDistanceFacetCollector extends AbstractFacetCollector { public static class Aggregator implements GeoPointFieldData.ValueInDocProc { - protected final double lat; - - protected final double lon; - - private final GeoDistance geoDistance; - - private final DistanceUnit unit; + private final GeoDistance.FixedSourceDistance fixedSourceDistance; private final GeoDistanceFacet.Entry[] entries; - public Aggregator(double lat, double lon, GeoDistance geoDistance, DistanceUnit unit, GeoDistanceFacet.Entry[] entries) { - this.lat = lat; - this.lon = lon; - this.geoDistance = geoDistance; - this.unit = unit; + public Aggregator(GeoDistance.FixedSourceDistance fixedSourceDistance, GeoDistanceFacet.Entry[] entries) { + this.fixedSourceDistance = fixedSourceDistance; this.entries = entries; } @Override public void onValue(int docId, double lat, double lon) { - double distance = geoDistance.calculate(this.lat, this.lon, lat, lon, unit); + double distance = fixedSourceDistance.calculate(lat, lon); for (GeoDistanceFacet.Entry entry : entries) { if (entry.foundInDoc) { continue; diff --git a/modules/elasticsearch/src/main/java/org/elasticsearch/search/facet/geodistance/ScriptGeoDistanceFacetCollector.java b/modules/elasticsearch/src/main/java/org/elasticsearch/search/facet/geodistance/ScriptGeoDistanceFacetCollector.java index e747e0d0a10..5c1afc40e38 100644 --- a/modules/elasticsearch/src/main/java/org/elasticsearch/search/facet/geodistance/ScriptGeoDistanceFacetCollector.java +++ b/modules/elasticsearch/src/main/java/org/elasticsearch/search/facet/geodistance/ScriptGeoDistanceFacetCollector.java @@ -45,7 +45,7 @@ public class ScriptGeoDistanceFacetCollector extends GeoDistanceFacetCollector { super(facetName, fieldName, lat, lon, unit, geoDistance, entries, context); this.script = context.scriptService().search(context.lookup(), scriptLang, script, params); - this.aggregator = new Aggregator(lat, lon, geoDistance, unit, entries); + this.aggregator = new Aggregator(fixedSourceDistance, entries); this.scriptAggregator = (Aggregator) this.aggregator; } @@ -66,28 +66,19 @@ public class ScriptGeoDistanceFacetCollector extends GeoDistanceFacetCollector { public static class Aggregator implements GeoPointFieldData.ValueInDocProc { - protected final double lat; - - protected final double lon; - - private final GeoDistance geoDistance; - - private final DistanceUnit unit; + private final GeoDistance.FixedSourceDistance fixedSourceDistance; private final GeoDistanceFacet.Entry[] entries; double scriptValue; - public Aggregator(double lat, double lon, GeoDistance geoDistance, DistanceUnit unit, GeoDistanceFacet.Entry[] entries) { - this.lat = lat; - this.lon = lon; - this.geoDistance = geoDistance; - this.unit = unit; + public Aggregator(GeoDistance.FixedSourceDistance fixedSourceDistance, GeoDistanceFacet.Entry[] entries) { + this.fixedSourceDistance = fixedSourceDistance; this.entries = entries; } @Override public void onValue(int docId, double lat, double lon) { - double distance = geoDistance.calculate(this.lat, this.lon, lat, lon, unit); + double distance = fixedSourceDistance.calculate(lat, lon); for (GeoDistanceFacet.Entry entry : entries) { if (entry.foundInDoc) { continue; diff --git a/modules/elasticsearch/src/main/java/org/elasticsearch/search/facet/geodistance/ValueGeoDistanceFacetCollector.java b/modules/elasticsearch/src/main/java/org/elasticsearch/search/facet/geodistance/ValueGeoDistanceFacetCollector.java index 6240420d213..e60cc605101 100644 --- a/modules/elasticsearch/src/main/java/org/elasticsearch/search/facet/geodistance/ValueGeoDistanceFacetCollector.java +++ b/modules/elasticsearch/src/main/java/org/elasticsearch/search/facet/geodistance/ValueGeoDistanceFacetCollector.java @@ -50,7 +50,7 @@ public class ValueGeoDistanceFacetCollector extends GeoDistanceFacetCollector { } this.indexValueFieldName = valueFieldName; this.valueFieldDataType = mapper.fieldDataType(); - this.aggregator = new Aggregator(lat, lon, geoDistance, unit, entries); + this.aggregator = new Aggregator(fixedSourceDistance, entries); } @Override protected void doSetNextReader(IndexReader reader, int docBase) throws IOException { @@ -60,30 +60,20 @@ public class ValueGeoDistanceFacetCollector extends GeoDistanceFacetCollector { public static class Aggregator implements GeoPointFieldData.ValueInDocProc { - protected final double lat; - - protected final double lon; - - private final GeoDistance geoDistance; - - private final DistanceUnit unit; - + private final GeoDistance.FixedSourceDistance fixedSourceDistance; private final GeoDistanceFacet.Entry[] entries; NumericFieldData valueFieldData; final ValueAggregator valueAggregator = new ValueAggregator(); - public Aggregator(double lat, double lon, GeoDistance geoDistance, DistanceUnit unit, GeoDistanceFacet.Entry[] entries) { - this.lat = lat; - this.lon = lon; - this.geoDistance = geoDistance; - this.unit = unit; + public Aggregator(GeoDistance.FixedSourceDistance fixedSourceDistance, GeoDistanceFacet.Entry[] entries) { + this.fixedSourceDistance = fixedSourceDistance; this.entries = entries; } @Override public void onValue(int docId, double lat, double lon) { - double distance = geoDistance.calculate(this.lat, this.lon, lat, lon, unit); + double distance = fixedSourceDistance.calculate(lat, lon); for (GeoDistanceFacet.Entry entry : entries) { if (entry.foundInDoc) { continue;