optimize distance based based calcs by reusing source location computation
This commit is contained in:
parent
d371619dd8
commit
4bacebe860
|
@ -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();
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in New Issue