From 7d6e2ea779fff777f8d6a97e3e356f404978c78e Mon Sep 17 00:00:00 2001 From: Florian Schilling Date: Thu, 19 Dec 2013 13:52:33 +0900 Subject: [PATCH] Geo clean Up ============ The default unit for measuring distances is *MILES* in most cases. This commit moves ES over to the *International System of Units* and make it work on a default which relates to *METERS* . Also the current structures of the `GeoBoundingBox Filter` changed in order to define the *Bounding* by setting abitrary corners. Distances --------- Since the default unit for measuring distances has changed to a default unit `DistanceUnit.DEFAULT` relating to *meters*, the **REST API** has changed at the following places: * `ScriptDocValues.factorDistance()` returns *meters* instead of *miles* * `ScriptDocValues.factorDistanceWithDefault()` returns *meters* instead of *miles* * `ScriptDocValues.arcDistance()` returns *meters* instead of *miles* one might use `ScriptDocValues.arcDistanceInMiles()` * `ScriptDocValues.arcDistanceWithDefault()` returns *meters* instead of *miles* * `ScriptDocValues.distance()` returns *meters* instead of *miles* one might use `ScriptDocValues.distanceInMiles()` * `ScriptDocValues.distanceWithDefault()` returns *meters* instead of *miles* one might use `ScriptDocValues.distanceInMilesWithDefault()` * `GeoDistanceFilter` default unit changes from *kilometers* to *meters* * `GeoDistanceRangeFilter` default unit changes from *miles* to *meters* * `GeoDistanceFacet` default unit changes from *miles* to *meters* Geo Bounding Box Filter ----------------------- The naming of the GeoBoundingBoxFilter properties allows to set arbitrary corners (see #4084) namely `top_right`, `top_left`, `bottom_right` and `bottom_left`. This change also includes the fields `topRight` and `bottomLeft` Also it is be possible to set the single values by using just `top`, `bottom`, `left` and `right` parameters. Closes #4515, #4084 --- docs/reference/api-conventions.asciidoc | 1 + .../filters/geo-bounding-box-filter.asciidoc | 32 +++++ .../search/facets/geo-distance-facet.asciidoc | 2 +- .../common/geo/GeoHashUtils.java | 20 +-- .../elasticsearch/common/geo/GeoPoint.java | 4 +- .../elasticsearch/common/geo/GeoUtils.java | 4 +- .../common/geo/builders/CircleBuilder.java | 5 +- .../common/geo/builders/EnvelopeBuilder.java | 29 ++--- .../common/geo/builders/ShapeBuilder.java | 11 +- .../common/unit/DistanceUnit.java | 64 +++++----- .../index/fielddata/ScriptDocValues.java | 45 +++++-- .../GeoPointCompressedIndexFieldData.java | 2 +- .../index/mapper/geo/GeoPointFieldMapper.java | 6 +- .../index/mapper/geo/GeoShapeFieldMapper.java | 2 +- .../query/GeoBoundingBoxFilterBuilder.java | 106 ++++++++++------ .../query/GeoBoundingBoxFilterParser.java | 63 ++++++++-- .../index/query/GeoDistanceFilterParser.java | 8 +- .../query/GeoDistanceRangeFilterParser.java | 14 +-- .../index/query/GeoPolygonFilterBuilder.java | 19 +-- .../index/query/GeoPolygonFilterParser.java | 28 +++-- .../index/query/GeoShapeFilterParser.java | 1 - .../index/query/GeohashCellFilter.java | 4 +- .../functionscore/DecayFunctionParser.java | 4 +- .../index/search/geo/GeoDistanceFilter.java | 4 +- .../search/geo/GeoDistanceRangeFilter.java | 8 +- .../index/search/geo/GeoPolygonFilter.java | 18 +-- .../geo/IndexedGeoBoundingBoxFilter.java | 16 +-- .../range/geodistance/GeoDistanceParser.java | 2 +- .../geodistance/GeoDistanceFacetParser.java | 2 +- .../search/sort/GeoDistanceSortParser.java | 2 +- .../common/unit/DistanceUnitTests.java | 31 +++-- .../index/mapper/geo/GeoMappingTests.java | 2 +- .../query/SimpleIndexQueryParserTests.java | 72 ++++++++--- .../index/query/geo_boundingbox5.json | 15 +++ .../index/query/geo_boundingbox6.json | 17 +++ .../search/geo/GeoDistanceTests.java | 117 ++++++++++-------- .../validate/SimpleValidateQueryTests.java | 15 ++- 37 files changed, 514 insertions(+), 281 deletions(-) create mode 100644 src/test/java/org/elasticsearch/index/query/geo_boundingbox5.json create mode 100644 src/test/java/org/elasticsearch/index/query/geo_boundingbox6.json diff --git a/docs/reference/api-conventions.asciidoc b/docs/reference/api-conventions.asciidoc index 0f1799fc3cf36..091393ec1ae6d 100644 --- a/docs/reference/api-conventions.asciidoc +++ b/docs/reference/api-conventions.asciidoc @@ -152,6 +152,7 @@ The full list of units is listed below: [horizontal] Mile:: `mi` or `miles` Yard:: `yd` or `yards` +Feet:: `ft` or `feet` Inch:: `in` or `inch` Kilometer:: `km` or `kilometers` Meter:: `m` or `meters` diff --git a/docs/reference/query-dsl/filters/geo-bounding-box-filter.asciidoc b/docs/reference/query-dsl/filters/geo-bounding-box-filter.asciidoc index 6782ad6c6883a..7f16ec562d99a 100644 --- a/docs/reference/query-dsl/filters/geo-bounding-box-filter.asciidoc +++ b/docs/reference/query-dsl/filters/geo-bounding-box-filter.asciidoc @@ -149,6 +149,38 @@ Format in `lat,lon`. } -------------------------------------------------- +[float] +==== Vertices + +The vertices of the bounding box can either be set by `top_left` and +`bottom_right` or by `top_right` and `bottom_left` parameters. More +over the names `topLeft`, `bottomRight`, `topRight` and `bottomLeft` +are supported. Instead of setting the values pairwise, one can use +the simple names `top`, `left`, `bottom` and `right` to set the +values separately. + +[source,js] +-------------------------------------------------- +{ + "filtered" : { + "query" : { + "match_all" : {} + }, + "filter" : { + "geo_bounding_box" : { + "pin.location" : { + "top" : -74.1, + "left" : 40.73, + "bottom" : -71.12, + "right" : 40.01 + } + } + } + } +} +-------------------------------------------------- + + [float] ==== geo_point Type diff --git a/docs/reference/search/facets/geo-distance-facet.asciidoc b/docs/reference/search/facets/geo-distance-facet.asciidoc index f6db797393950..e56f4bda73685 100644 --- a/docs/reference/search/facets/geo-distance-facet.asciidoc +++ b/docs/reference/search/facets/geo-distance-facet.asciidoc @@ -169,7 +169,7 @@ itself. |======================================================================= |Option |Description |`unit` |The unit the ranges are provided in. Defaults to `km`. Can also -be `mi`, `miles`, `in`, `inch`, `yd`, `yards`, `kilometers`, `mm`, `millimeters`, `cm`, `centimeters`, `m` or `meters`. +be `mi`, `miles`, `in`, `inch`, `yd`, `yards`, `ft`, `feet`, `kilometers`, `mm`, `millimeters`, `cm`, `centimeters`, `m` or `meters`. |`distance_type` |How to compute the distance. Can either be `arc` (better precision), `sloppy_arc` (faster) or `plane` (fastest). Defaults to `sloppy_arc`. diff --git a/src/main/java/org/elasticsearch/common/geo/GeoHashUtils.java b/src/main/java/org/elasticsearch/common/geo/GeoHashUtils.java index dfcb7e1cd4a8c..d24cfbfd775af 100644 --- a/src/main/java/org/elasticsearch/common/geo/GeoHashUtils.java +++ b/src/main/java/org/elasticsearch/common/geo/GeoHashUtils.java @@ -281,22 +281,26 @@ private static final int decode(char geo) { } } + /** + * Decodes the given geohash + * + * @param geohash Geohash to decocde + * @return {@link GeoPoint} at the center of cell, given by the geohash + */ public static GeoPoint decode(String geohash) { - GeoPoint point = new GeoPoint(); - decode(geohash, point); - return point; + return decode(geohash, new GeoPoint()); } /** * Decodes the given geohash into a latitude and longitude * - * @param geohash Geohash to deocde - * @return Array with the latitude at index 0, and longitude at index 1 + * @param geohash Geohash to decocde + * @return the given {@link GeoPoint} reseted to the center of + * cell, given by the geohash */ - public static void decode(String geohash, GeoPoint ret) { + public static GeoPoint decode(String geohash, GeoPoint ret) { double[] interval = decodeCell(geohash); - ret.reset((interval[0] + interval[1]) / 2D, (interval[2] + interval[3]) / 2D); - + return ret.reset((interval[0] + interval[1]) / 2D, (interval[2] + interval[3]) / 2D); } /** diff --git a/src/main/java/org/elasticsearch/common/geo/GeoPoint.java b/src/main/java/org/elasticsearch/common/geo/GeoPoint.java index 9ff03cb63d5e9..434aae5010e13 100644 --- a/src/main/java/org/elasticsearch/common/geo/GeoPoint.java +++ b/src/main/java/org/elasticsearch/common/geo/GeoPoint.java @@ -19,13 +19,13 @@ package org.elasticsearch.common.geo; -import java.io.IOException; - import org.elasticsearch.ElasticsearchParseException; import org.elasticsearch.common.xcontent.XContentParser; import org.elasticsearch.common.xcontent.XContentParser.Token; import org.elasticsearch.index.mapper.geo.GeoPointFieldMapper; +import java.io.IOException; + /** * */ diff --git a/src/main/java/org/elasticsearch/common/geo/GeoUtils.java b/src/main/java/org/elasticsearch/common/geo/GeoUtils.java index f01a395d55097..2efc6eb50d222 100644 --- a/src/main/java/org/elasticsearch/common/geo/GeoUtils.java +++ b/src/main/java/org/elasticsearch/common/geo/GeoUtils.java @@ -137,7 +137,7 @@ public static int quadTreeLevelsForPrecision(double meters) { * @return levels need to achieve precision */ public static int quadTreeLevelsForPrecision(String distance) { - return quadTreeLevelsForPrecision(DistanceUnit.parse(distance, DistanceUnit.METERS, DistanceUnit.METERS)); + return quadTreeLevelsForPrecision(DistanceUnit.METERS.parse(distance, DistanceUnit.DEFAULT)); } /** @@ -173,7 +173,7 @@ public static int geoHashLevelsForPrecision(double meters) { * @return levels need to achieve precision */ public static int geoHashLevelsForPrecision(String distance) { - return geoHashLevelsForPrecision(DistanceUnit.parse(distance, DistanceUnit.METERS, DistanceUnit.METERS)); + return geoHashLevelsForPrecision(DistanceUnit.METERS.parse(distance, DistanceUnit.DEFAULT)); } /** diff --git a/src/main/java/org/elasticsearch/common/geo/builders/CircleBuilder.java b/src/main/java/org/elasticsearch/common/geo/builders/CircleBuilder.java index baef9d79db110..5792668ba5b5b 100644 --- a/src/main/java/org/elasticsearch/common/geo/builders/CircleBuilder.java +++ b/src/main/java/org/elasticsearch/common/geo/builders/CircleBuilder.java @@ -19,14 +19,13 @@ package org.elasticsearch.common.geo.builders; -import java.io.IOException; - import org.elasticsearch.common.unit.DistanceUnit; import org.elasticsearch.common.unit.DistanceUnit.Distance; import org.elasticsearch.common.xcontent.XContentBuilder; import com.spatial4j.core.shape.Circle; import com.vividsolutions.jts.geom.Coordinate; +import java.io.IOException; public class CircleBuilder extends ShapeBuilder { @@ -64,7 +63,7 @@ public CircleBuilder center(double lon, double lat) { * @return this */ public CircleBuilder radius(String radius) { - return radius(DistanceUnit.Distance.parseDistance(radius, DistanceUnit.METERS)); + return radius(DistanceUnit.Distance.parseDistance(radius)); } /** diff --git a/src/main/java/org/elasticsearch/common/geo/builders/EnvelopeBuilder.java b/src/main/java/org/elasticsearch/common/geo/builders/EnvelopeBuilder.java index acc759a286222..9de216be18044 100644 --- a/src/main/java/org/elasticsearch/common/geo/builders/EnvelopeBuilder.java +++ b/src/main/java/org/elasticsearch/common/geo/builders/EnvelopeBuilder.java @@ -19,22 +19,21 @@ package org.elasticsearch.common.geo.builders; -import java.io.IOException; - -import org.elasticsearch.common.xcontent.XContentBuilder; - import com.spatial4j.core.shape.Rectangle; import com.vividsolutions.jts.geom.Coordinate; +import org.elasticsearch.common.xcontent.XContentBuilder; + +import java.io.IOException; public class EnvelopeBuilder extends ShapeBuilder { public static final GeoShapeType TYPE = GeoShapeType.ENVELOPE; - protected Coordinate northEast; - protected Coordinate southWest; - - public EnvelopeBuilder topLeft(Coordinate northEast) { - this.northEast = northEast; + protected Coordinate topLeft; + protected Coordinate bottomRight; + + public EnvelopeBuilder topLeft(Coordinate topLeft) { + this.topLeft = topLeft; return this; } @@ -42,8 +41,8 @@ public EnvelopeBuilder topLeft(double longitude, double latitude) { return topLeft(coordinate(longitude, latitude)); } - public EnvelopeBuilder bottomRight(Coordinate southWest) { - this.southWest = southWest; + public EnvelopeBuilder bottomRight(Coordinate bottomRight) { + this.bottomRight = bottomRight; return this; } @@ -56,17 +55,15 @@ public XContentBuilder toXContent(XContentBuilder builder, Params params) throws builder.startObject(); builder.field(FIELD_TYPE, TYPE.shapename); builder.startArray(FIELD_COORDINATES); - toXContent(builder, northEast); - toXContent(builder, southWest); + toXContent(builder, topLeft); + toXContent(builder, bottomRight); builder.endArray(); return builder.endObject(); } @Override public Rectangle build() { - return SPATIAL_CONTEXT.makeRectangle( - northEast.x, southWest.x, - southWest.y, northEast.y); + return SPATIAL_CONTEXT.makeRectangle(topLeft.x, bottomRight.x, bottomRight.y, topLeft.y); } @Override diff --git a/src/main/java/org/elasticsearch/common/geo/builders/ShapeBuilder.java b/src/main/java/org/elasticsearch/common/geo/builders/ShapeBuilder.java index aefb7bba6f091..aab106836cb16 100644 --- a/src/main/java/org/elasticsearch/common/geo/builders/ShapeBuilder.java +++ b/src/main/java/org/elasticsearch/common/geo/builders/ShapeBuilder.java @@ -19,14 +19,10 @@ package org.elasticsearch.common.geo.builders; -import java.io.IOException; -import java.util.*; - import org.elasticsearch.ElasticsearchIllegalArgumentException; import org.elasticsearch.ElasticsearchParseException; import org.elasticsearch.common.logging.ESLogger; import org.elasticsearch.common.logging.ESLoggerFactory; -import org.elasticsearch.common.unit.DistanceUnit; import org.elasticsearch.common.unit.DistanceUnit.Distance; import org.elasticsearch.common.xcontent.ToXContent; import org.elasticsearch.common.xcontent.XContent; @@ -38,7 +34,12 @@ import com.spatial4j.core.shape.Shape; import com.vividsolutions.jts.geom.Coordinate; import com.vividsolutions.jts.geom.GeometryFactory; +import java.io.IOException; +import java.util.*; +/** + * Basic class for building GeoJSON shapes like Polygons, Linestrings, etc + */ public abstract class ShapeBuilder implements ToXContent { protected static final ESLogger LOGGER = ESLoggerFactory.getLogger(ShapeBuilder.class.getName()); @@ -541,7 +542,7 @@ public static ShapeBuilder parse(XContentParser parser) throws IOException { node = parseCoordinates(parser); } else if (CircleBuilder.FIELD_RADIUS.equals(fieldName)) { parser.nextToken(); - radius = Distance.parseDistance(parser.text(), DistanceUnit.METERS); + radius = Distance.parseDistance(parser.text()); } else { parser.nextToken(); parser.skipChildren(); diff --git a/src/main/java/org/elasticsearch/common/unit/DistanceUnit.java b/src/main/java/org/elasticsearch/common/unit/DistanceUnit.java index ed0f5f9176078..d1db86fdeb2be 100644 --- a/src/main/java/org/elasticsearch/common/unit/DistanceUnit.java +++ b/src/main/java/org/elasticsearch/common/unit/DistanceUnit.java @@ -30,25 +30,29 @@ * The DistanceUnit enumerates several units for measuring distances. These units * provide methods for converting strings and methods to convert units among each * others. Some methods like {@link DistanceUnit#getEarthCircumference} refer to - * the earth ellipsoid defined in {@link GeoUtils}. + * the earth ellipsoid defined in {@link GeoUtils}. The default unit used within + * this project is METERS which is defined by DEFAULT */ public enum DistanceUnit { INCH(0.0254, "in", "inch"), YARD(0.9144, "yd", "yards"), + FEET(0.3048, "ft", "feet"), MILES(1609.344, "mi", "miles"), KILOMETERS(1000.0, "km", "kilometers"), MILLIMETERS(0.001, "mm", "millimeters"), CENTIMETERS(0.01, "cm", "centimeters"), - + // since 'm' is suffix of other unit // it must be the last entry of unit // names ending with 'm'. otherwise // parsing would fail - METERS(1, "m", "meters"); + METERS(1, "m", "meters"); + + public static DistanceUnit DEFAULT = METERS; private double meters; private final String[] names; - + DistanceUnit(double meters, String...names) { this.meters = meters; this.names = names; @@ -81,26 +85,6 @@ public double getDistancePerDegree() { return GeoUtils.EARTH_EQUATOR / (360.0 * meters); } - /** - * Convert a value into miles - * - * @param distance distance in this unit - * @return value in miles - */ - public double toMiles(double distance) { - return convert(distance, this, DistanceUnit.MILES); - } - - /** - * Convert a value into kilometers - * - * @param distance distance in this unit - * @return value in kilometers - */ - public double toKilometers(double distance) { - return convert(distance, this, DistanceUnit.KILOMETERS); - } - /** * Convert a value into meters * @@ -125,11 +109,11 @@ public double fromMeters(double distance) { * Convert a given value into another unit * * @param distance value in this unit - * @param unit target unit - * @return value of the target unit + * @param unit source unit + * @return value in this unit */ public double convert(double distance, DistanceUnit unit) { - return convert(distance, this, unit); + return convert(distance, unit, this); } /** @@ -141,7 +125,7 @@ public double convert(double distance, DistanceUnit unit) { public String toString(double distance) { return distance + toString(); } - + @Override public String toString() { return names[0]; @@ -176,6 +160,17 @@ public static double parse(String distance, DistanceUnit defaultUnit, DistanceUn return convert(dist.value, dist.unit, to); } + /** + * Parses a given distance and converts it to this unit. + * + * @param distance String defining a distance (value and unit) + * @param defaultUnit unit to expect if none if provided + * @return parsed distance + */ + public double parse(String distance, DistanceUnit defaultUnit) { + return parse(distance, defaultUnit, this); + } + /** * Convert a String to a {@link DistanceUnit} * @@ -296,6 +291,17 @@ public String toString() { return unit.toString(value); } + /** + * Parse a {@link Distance} from a given String. If no unit is given + * DistanceUnit.DEFAULT will be used + * + * @param distance String defining a {@link Distance} + * @return parsed {@link Distance} + */ + public static Distance parseDistance(String distance) { + return parseDistance(distance, DEFAULT); + } + /** * Parse a {@link Distance} from a given String * @@ -304,7 +310,7 @@ public String toString() { * if not unit is provided in the first argument * @return parsed {@link Distance} */ - public static Distance parseDistance(String distance, DistanceUnit defaultUnit) { + private static Distance parseDistance(String distance, DistanceUnit defaultUnit) { for (DistanceUnit unit : values()) { for (String name : unit.names) { if(distance.endsWith(name)) { diff --git a/src/main/java/org/elasticsearch/index/fielddata/ScriptDocValues.java b/src/main/java/org/elasticsearch/index/fielddata/ScriptDocValues.java index bed56b762fcd3..2e56d580b10ae 100644 --- a/src/main/java/org/elasticsearch/index/fielddata/ScriptDocValues.java +++ b/src/main/java/org/elasticsearch/index/fielddata/ScriptDocValues.java @@ -136,7 +136,6 @@ public List getValues() { } - public static class Longs extends ScriptDocValues { private final LongValues values; @@ -252,7 +251,6 @@ public void grow(int newLength) { }; } - @Override public boolean isEmpty() { return values.setDocument(docId) == 0; @@ -292,7 +290,6 @@ public double getLon() { return getValue().lon(); } - public List getValues() { if (!listLoaded) { int numValues = values.setDocument(docId); @@ -316,7 +313,7 @@ public List getValues() { public double factorDistance(double lat, double lon) { GeoPoint point = getValue(); - return GeoDistance.FACTOR.calculate(point.lat(), point.lon(), lat, lon, DistanceUnit.MILES); + return GeoDistance.FACTOR.calculate(point.lat(), point.lon(), lat, lon, DistanceUnit.DEFAULT); } public double factorDistanceWithDefault(double lat, double lon, double defaultValue) { @@ -324,22 +321,22 @@ public double factorDistanceWithDefault(double lat, double lon, double defaultVa return defaultValue; } GeoPoint point = getValue(); - return GeoDistance.FACTOR.calculate(point.lat(), point.lon(), lat, lon, DistanceUnit.MILES); + return GeoDistance.FACTOR.calculate(point.lat(), point.lon(), lat, lon, DistanceUnit.DEFAULT); } public double factorDistance02(double lat, double lon) { GeoPoint point = getValue(); - return GeoDistance.FACTOR.calculate(point.lat(), point.lon(), lat, lon, DistanceUnit.MILES) + 1; + return GeoDistance.FACTOR.calculate(point.lat(), point.lon(), lat, lon, DistanceUnit.DEFAULT) + 1; } public double factorDistance13(double lat, double lon) { GeoPoint point = getValue(); - return GeoDistance.FACTOR.calculate(point.lat(), point.lon(), lat, lon, DistanceUnit.MILES) + 2; + return GeoDistance.FACTOR.calculate(point.lat(), point.lon(), lat, lon, DistanceUnit.DEFAULT) + 2; } public double arcDistance(double lat, double lon) { GeoPoint point = getValue(); - return GeoDistance.ARC.calculate(point.lat(), point.lon(), lat, lon, DistanceUnit.MILES); + return GeoDistance.ARC.calculate(point.lat(), point.lon(), lat, lon, DistanceUnit.DEFAULT); } public double arcDistanceWithDefault(double lat, double lon, double defaultValue) { @@ -347,7 +344,7 @@ public double arcDistanceWithDefault(double lat, double lon, double defaultValue return defaultValue; } GeoPoint point = getValue(); - return GeoDistance.ARC.calculate(point.lat(), point.lon(), lat, lon, DistanceUnit.MILES); + return GeoDistance.ARC.calculate(point.lat(), point.lon(), lat, lon, DistanceUnit.DEFAULT); } public double arcDistanceInKm(double lat, double lon) { @@ -363,9 +360,22 @@ public double arcDistanceInKmWithDefault(double lat, double lon, double defaultV return GeoDistance.ARC.calculate(point.lat(), point.lon(), lat, lon, DistanceUnit.KILOMETERS); } + public double arcDistanceInMiles(double lat, double lon) { + GeoPoint point = getValue(); + return GeoDistance.ARC.calculate(point.lat(), point.lon(), lat, lon, DistanceUnit.MILES); + } + + public double arcDistanceInMilesWithDefault(double lat, double lon, double defaultValue) { + if (isEmpty()) { + return defaultValue; + } + GeoPoint point = getValue(); + return GeoDistance.ARC.calculate(point.lat(), point.lon(), lat, lon, DistanceUnit.MILES); + } + public double distance(double lat, double lon) { GeoPoint point = getValue(); - return GeoDistance.PLANE.calculate(point.lat(), point.lon(), lat, lon, DistanceUnit.MILES); + return GeoDistance.PLANE.calculate(point.lat(), point.lon(), lat, lon, DistanceUnit.DEFAULT); } public double distanceWithDefault(double lat, double lon, double defaultValue) { @@ -373,7 +383,7 @@ public double distanceWithDefault(double lat, double lon, double defaultValue) { return defaultValue; } GeoPoint point = getValue(); - return GeoDistance.PLANE.calculate(point.lat(), point.lon(), lat, lon, DistanceUnit.MILES); + return GeoDistance.PLANE.calculate(point.lat(), point.lon(), lat, lon, DistanceUnit.DEFAULT); } public double distanceInKm(double lat, double lon) { @@ -388,5 +398,18 @@ public double distanceInKmWithDefault(double lat, double lon, double defaultValu GeoPoint point = getValue(); return GeoDistance.PLANE.calculate(point.lat(), point.lon(), lat, lon, DistanceUnit.KILOMETERS); } + + public double distanceInMiles(double lat, double lon) { + GeoPoint point = getValue(); + return GeoDistance.PLANE.calculate(point.lat(), point.lon(), lat, lon, DistanceUnit.MILES); + } + + public double distanceInMilesWithDefault(double lat, double lon, double defaultValue) { + if (isEmpty()) { + return defaultValue; + } + GeoPoint point = getValue(); + return GeoDistance.PLANE.calculate(point.lat(), point.lon(), lat, lon, DistanceUnit.MILES); + } } } diff --git a/src/main/java/org/elasticsearch/index/fielddata/plain/GeoPointCompressedIndexFieldData.java b/src/main/java/org/elasticsearch/index/fielddata/plain/GeoPointCompressedIndexFieldData.java index 2415f86b8865c..882cb3a36b434 100644 --- a/src/main/java/org/elasticsearch/index/fielddata/plain/GeoPointCompressedIndexFieldData.java +++ b/src/main/java/org/elasticsearch/index/fielddata/plain/GeoPointCompressedIndexFieldData.java @@ -56,7 +56,7 @@ public IndexFieldData build(Index index, @IndexSettings Settings indexSetting final String precisionAsString = type.getSettings().get(PRECISION_KEY); final Distance precision; if (precisionAsString != null) { - precision = Distance.parseDistance(precisionAsString, DistanceUnit.METERS); + precision = Distance.parseDistance(precisionAsString); } else { precision = DEFAULT_PRECISION_VALUE; } diff --git a/src/main/java/org/elasticsearch/index/mapper/geo/GeoPointFieldMapper.java b/src/main/java/org/elasticsearch/index/mapper/geo/GeoPointFieldMapper.java index f277e13ab082a..47178efd8ede1 100644 --- a/src/main/java/org/elasticsearch/index/mapper/geo/GeoPointFieldMapper.java +++ b/src/main/java/org/elasticsearch/index/mapper/geo/GeoPointFieldMapper.java @@ -298,11 +298,11 @@ private Encoding(int numBytes) { assert (1L << (numBytesPerCoordinate * 8 - 1)) * factor > 180 && (1L << (numBytesPerCoordinate * 8 - 2)) * factor < 180 : numBytesPerCoordinate + " " + factor; if (numBytes == MAX_NUM_BYTES) { // no precision loss compared to a double - precision = new DistanceUnit.Distance(0, DistanceUnit.METERS); + precision = new DistanceUnit.Distance(0, DistanceUnit.DEFAULT); } else { precision = new DistanceUnit.Distance( - GeoDistance.PLANE.calculate(0, 0, factor / 2, factor / 2, DistanceUnit.METERS), // factor/2 because we use Math.round instead of a cast to convert the double to a long - DistanceUnit.METERS); + GeoDistance.PLANE.calculate(0, 0, factor / 2, factor / 2, DistanceUnit.DEFAULT), // factor/2 because we use Math.round instead of a cast to convert the double to a long + DistanceUnit.DEFAULT); } } diff --git a/src/main/java/org/elasticsearch/index/mapper/geo/GeoShapeFieldMapper.java b/src/main/java/org/elasticsearch/index/mapper/geo/GeoShapeFieldMapper.java index 69bbab435f85c..1b83cd49095cb 100644 --- a/src/main/java/org/elasticsearch/index/mapper/geo/GeoShapeFieldMapper.java +++ b/src/main/java/org/elasticsearch/index/mapper/geo/GeoShapeFieldMapper.java @@ -179,7 +179,7 @@ public Mapper.Builder parse(String name, Map node, ParserContext } else if (Names.TREE_LEVELS.equals(fieldName)) { builder.treeLevels(Integer.parseInt(fieldNode.toString())); } else if (Names.TREE_PRESISION.equals(fieldName)) { - builder.treeLevelsByDistance(DistanceUnit.parse(fieldNode.toString(), DistanceUnit.METERS, DistanceUnit.METERS)); + builder.treeLevelsByDistance(DistanceUnit.parse(fieldNode.toString(), DistanceUnit.DEFAULT, DistanceUnit.DEFAULT)); } else if (Names.DISTANCE_ERROR_PCT.equals(fieldName)) { builder.distanceErrorPct(Double.parseDouble(fieldNode.toString())); } else if (Names.STRATEGY.equals(fieldName)) { diff --git a/src/main/java/org/elasticsearch/index/query/GeoBoundingBoxFilterBuilder.java b/src/main/java/org/elasticsearch/index/query/GeoBoundingBoxFilterBuilder.java index ad65f08932681..c2133f10d7760 100644 --- a/src/main/java/org/elasticsearch/index/query/GeoBoundingBoxFilterBuilder.java +++ b/src/main/java/org/elasticsearch/index/query/GeoBoundingBoxFilterBuilder.java @@ -31,21 +31,22 @@ */ public class GeoBoundingBoxFilterBuilder extends BaseFilterBuilder { + public static final String TOP_LEFT = GeoBoundingBoxFilterParser.TOP_LEFT; + public static final String BOTTOM_RIGHT = GeoBoundingBoxFilterParser.BOTTOM_RIGHT; + + private static final int TOP = 0; + private static final int LEFT = 1; + private static final int BOTTOM = 2; + private static final int RIGHT = 3; + private final String name; - private GeoPoint topLeft; - - private String topLeftGeohash; - - private GeoPoint bottomRight; - - private String bottomRightGeohash; + private double[] box = {Double.NaN, Double.NaN, Double.NaN, Double.NaN}; private Boolean cache; private String cacheKey; private String filterName; - private String type; public GeoBoundingBoxFilterBuilder(String name) { @@ -59,43 +60,78 @@ public GeoBoundingBoxFilterBuilder(String name) { * @param lon The longitude */ public GeoBoundingBoxFilterBuilder topLeft(double lat, double lon) { - topLeft = new GeoPoint(lat, lon); + box[TOP] = lat; + box[LEFT] = lon; return this; } + public GeoBoundingBoxFilterBuilder topLeft(GeoPoint point) { + return topLeft(point.lat(), point.lon()); + } + + public GeoBoundingBoxFilterBuilder topLeft(String geohash) { + return topLeft(GeoHashUtils.decode(geohash)); + } + /** - * Adds bottom right point. + * Adds bottom right corner. * * @param lat The latitude * @param lon The longitude */ public GeoBoundingBoxFilterBuilder bottomRight(double lat, double lon) { - bottomRight = new GeoPoint(lat, lon); + box[BOTTOM] = lat; + box[RIGHT] = lon; return this; } - public GeoBoundingBoxFilterBuilder topLeft(String geohash) { - this.topLeftGeohash = geohash; - return this; + public GeoBoundingBoxFilterBuilder bottomRight(GeoPoint point) { + return bottomRight(point.lat(), point.lon()); } public GeoBoundingBoxFilterBuilder bottomRight(String geohash) { - this.bottomRightGeohash = geohash; + return bottomRight(GeoHashUtils.decode(geohash)); + } + + /** + * Adds bottom left corner. + * + * @param lat The latitude + * @param lon The longitude + */ + public GeoBoundingBoxFilterBuilder bottomLeft(double lat, double lon) { + box[BOTTOM] = lat; + box[LEFT] = lon; return this; } + public GeoBoundingBoxFilterBuilder bottomLeft(GeoPoint point) { + return bottomLeft(point.lat(), point.lon()); + } + + public GeoBoundingBoxFilterBuilder bottomLeft(String geohash) { + return bottomLeft(GeoHashUtils.decode(geohash)); + } + /** - * Adds top left and bottom right by geohash cell. + * Adds top right point. * - * @param geohash the geohash of the cell definign the boundingbox + * @param lat The latitude + * @param lon The longitude */ - public GeoBoundingBoxFilterBuilder geohash(String geohash) { - topLeft = new GeoPoint(); - bottomRight = new GeoPoint(); - GeoHashUtils.decodeCell(geohash, topLeft, bottomRight); + public GeoBoundingBoxFilterBuilder topRight(double lat, double lon) { + box[TOP] = lat; + box[RIGHT] = lon; return this; } + public GeoBoundingBoxFilterBuilder topRight(GeoPoint point) { + return topRight(point.lat(), point.lon()); + } + + public GeoBoundingBoxFilterBuilder topRight(String geohash) { + return topRight(GeoHashUtils.decode(geohash)); + } /** * Sets the filter name for the filter that can be used when searching for matched_filters per hit. @@ -129,24 +165,22 @@ public GeoBoundingBoxFilterBuilder type(String type) { @Override protected void doXContent(XContentBuilder builder, Params params) throws IOException { + // check values + if(Double.isNaN(box[TOP])) { + throw new ElasticsearchIllegalArgumentException("geo_bounding_box requires top latitude to be set"); + } else if(Double.isNaN(box[BOTTOM])) { + throw new ElasticsearchIllegalArgumentException("geo_bounding_box requires bottom latitude to be set"); + } else if(Double.isNaN(box[RIGHT])) { + throw new ElasticsearchIllegalArgumentException("geo_bounding_box requires right longitude to be set"); + } else if(Double.isNaN(box[LEFT])) { + throw new ElasticsearchIllegalArgumentException("geo_bounding_box requires left longitude to be set"); + } + builder.startObject(GeoBoundingBoxFilterParser.NAME); builder.startObject(name); - if (topLeftGeohash != null) { - builder.field("top_left", topLeftGeohash); - } else if (topLeft != null) { - builder.startArray("top_left").value(topLeft.lon()).value(topLeft.lat()).endArray(); - } else { - throw new ElasticsearchIllegalArgumentException("geo_bounding_box requires 'top_left' to be set"); - } - - if (bottomRightGeohash != null) { - builder.field("bottom_right", bottomRightGeohash); - } else if (bottomRight != null) { - builder.startArray("bottom_right").value(bottomRight.lon()).value(bottomRight.lat()).endArray(); - } else { - throw new ElasticsearchIllegalArgumentException("geo_bounding_box requires 'bottom_right' to be set"); - } + builder.array(TOP_LEFT, box[LEFT], box[TOP]); + builder.array(BOTTOM_RIGHT, box[RIGHT], box[BOTTOM]); builder.endObject(); if (filterName != null) { diff --git a/src/main/java/org/elasticsearch/index/query/GeoBoundingBoxFilterParser.java b/src/main/java/org/elasticsearch/index/query/GeoBoundingBoxFilterParser.java index a632091aa6093..85f7b589a3af1 100644 --- a/src/main/java/org/elasticsearch/index/query/GeoBoundingBoxFilterParser.java +++ b/src/main/java/org/elasticsearch/index/query/GeoBoundingBoxFilterParser.java @@ -42,11 +42,22 @@ */ public class GeoBoundingBoxFilterParser implements FilterParser { - public static final String NAME = "geo_bbox"; - public static final String TOP_LEFT = "top_left"; + public static final String TOP = "top"; + public static final String LEFT = "left"; + public static final String RIGHT = "right"; + public static final String BOTTOM = "bottom"; + + public static final String TOP_LEFT = TOP + "_" + LEFT; + public static final String TOP_RIGHT = TOP + "_" + RIGHT; + public static final String BOTTOM_LEFT = BOTTOM + "_" + LEFT; + public static final String BOTTOM_RIGHT = BOTTOM + "_" + RIGHT; + public static final String TOPLEFT = "topLeft"; - public static final String BOTTOM_RIGHT = "bottom_right"; + public static final String TOPRIGHT = "topRight"; + public static final String BOTTOMLEFT = "bottomLeft"; public static final String BOTTOMRIGHT = "bottomRight"; + + public static final String NAME = "geo_bbox"; public static final String FIELD = "field"; @Inject @@ -65,14 +76,19 @@ public Filter parse(QueryParseContext parseContext) throws IOException, QueryPar boolean cache = false; CacheKeyFilter.Key cacheKey = null; String fieldName = null; - GeoPoint topLeft = new GeoPoint(); - GeoPoint bottomRight = new GeoPoint(); + double top = Double.NaN; + double bottom = Double.NaN; + double left = Double.NaN; + double right = Double.NaN; + String filterName = null; String currentFieldName = null; XContentParser.Token token; boolean normalize = true; + GeoPoint sparse = new GeoPoint(); + String type = "memory"; while ((token = parser.nextToken()) != XContentParser.Token.END_OBJECT) { @@ -87,12 +103,34 @@ public Filter parse(QueryParseContext parseContext) throws IOException, QueryPar token = parser.nextToken(); if (FIELD.equals(currentFieldName)) { fieldName = parser.text(); - } else if (TOP_LEFT.equals(currentFieldName) || TOPLEFT.equals(currentFieldName)) { - GeoPoint.parse(parser, topLeft); - } else if ( BOTTOM_RIGHT.equals(currentFieldName) || BOTTOMRIGHT.equals(currentFieldName)) { - GeoPoint.parse(parser, bottomRight); + } else if (TOP.equals(currentFieldName)) { + top = parser.doubleValue(); + } else if (BOTTOM.equals(currentFieldName)) { + bottom = parser.doubleValue(); + } else if (LEFT.equals(currentFieldName)) { + left = parser.doubleValue(); + } else if (RIGHT.equals(currentFieldName)) { + right = parser.doubleValue(); } else { - throw new ElasticsearchParseException("Unexpected field [" + currentFieldName + "]"); + if (TOP_LEFT.equals(currentFieldName) || TOPLEFT.equals(currentFieldName)) { + GeoPoint.parse(parser, sparse); + top = sparse.getLat(); + left = sparse.getLon(); + } else if (BOTTOM_RIGHT.equals(currentFieldName) || BOTTOMRIGHT.equals(currentFieldName)) { + GeoPoint.parse(parser, sparse); + bottom = sparse.getLat(); + right = sparse.getLon(); + } else if (TOP_RIGHT.equals(currentFieldName) || TOPRIGHT.equals(currentFieldName)) { + GeoPoint.parse(parser, sparse); + top = sparse.getLat(); + right = sparse.getLon(); + } else if (BOTTOM_LEFT.equals(currentFieldName) || BOTTOMLEFT.equals(currentFieldName)) { + GeoPoint.parse(parser, sparse); + bottom = sparse.getLat(); + left = sparse.getLon(); + } else { + throw new ElasticsearchParseException("Unexpected field [" + currentFieldName + "]"); + } } } else { throw new ElasticsearchParseException("fieldname expected but [" + token + "] found"); @@ -115,6 +153,9 @@ public Filter parse(QueryParseContext parseContext) throws IOException, QueryPar } } + final GeoPoint topLeft = sparse.reset(top, left); //just keep the object + final GeoPoint bottomRight = new GeoPoint(bottom, right); + if (normalize) { GeoUtils.normalizePoint(topLeft); GeoUtils.normalizePoint(bottomRight); @@ -148,5 +189,5 @@ public Filter parse(QueryParseContext parseContext) throws IOException, QueryPar parseContext.addNamedFilter(filterName, filter); } return filter; - } + } } diff --git a/src/main/java/org/elasticsearch/index/query/GeoDistanceFilterParser.java b/src/main/java/org/elasticsearch/index/query/GeoDistanceFilterParser.java index 59e5758400137..0d7f2bff589aa 100644 --- a/src/main/java/org/elasticsearch/index/query/GeoDistanceFilterParser.java +++ b/src/main/java/org/elasticsearch/index/query/GeoDistanceFilterParser.java @@ -73,7 +73,7 @@ public Filter parse(QueryParseContext parseContext) throws IOException, QueryPar String fieldName = null; double distance = 0; Object vDistance = null; - DistanceUnit unit = DistanceUnit.KILOMETERS; // default unit + DistanceUnit unit = DistanceUnit.DEFAULT; GeoDistance geoDistance = GeoDistance.DEFAULT; String optimizeBbox = "memory"; boolean normalizeLon = true; @@ -142,11 +142,11 @@ public Filter parse(QueryParseContext parseContext) throws IOException, QueryPar } if (vDistance instanceof Number) { - distance = unit.toMiles(((Number) vDistance).doubleValue()); + distance = DistanceUnit.DEFAULT.convert(((Number) vDistance).doubleValue(), unit); } else { - distance = DistanceUnit.parse((String) vDistance, unit, DistanceUnit.MILES); + distance = DistanceUnit.parse((String) vDistance, unit, DistanceUnit.DEFAULT); } - distance = geoDistance.normalize(distance, DistanceUnit.MILES); + distance = geoDistance.normalize(distance, DistanceUnit.DEFAULT); if (normalizeLat || normalizeLon) { GeoUtils.normalizePoint(point, normalizeLat, normalizeLon); diff --git a/src/main/java/org/elasticsearch/index/query/GeoDistanceRangeFilterParser.java b/src/main/java/org/elasticsearch/index/query/GeoDistanceRangeFilterParser.java index ebd426838d97b..e411fb0131153 100644 --- a/src/main/java/org/elasticsearch/index/query/GeoDistanceRangeFilterParser.java +++ b/src/main/java/org/elasticsearch/index/query/GeoDistanceRangeFilterParser.java @@ -75,7 +75,7 @@ public Filter parse(QueryParseContext parseContext) throws IOException, QueryPar Object vTo = null; boolean includeLower = true; boolean includeUpper = true; - DistanceUnit unit = DistanceUnit.KILOMETERS; // default unit + DistanceUnit unit = DistanceUnit.DEFAULT; GeoDistance geoDistance = GeoDistance.DEFAULT; String optimizeBbox = "memory"; boolean normalizeLon = true; @@ -176,19 +176,19 @@ public Filter parse(QueryParseContext parseContext) throws IOException, QueryPar Double to = null; if (vFrom != null) { if (vFrom instanceof Number) { - from = unit.toMiles(((Number) vFrom).doubleValue()); + from = unit.toMeters(((Number) vFrom).doubleValue()); } else { - from = DistanceUnit.parse((String) vFrom, unit, DistanceUnit.MILES); + from = DistanceUnit.parse((String) vFrom, unit, DistanceUnit.DEFAULT); } - from = geoDistance.normalize(from, DistanceUnit.MILES); + from = geoDistance.normalize(from, DistanceUnit.DEFAULT); } if (vTo != null) { if (vTo instanceof Number) { - to = unit.toMiles(((Number) vTo).doubleValue()); + to = unit.toMeters(((Number) vTo).doubleValue()); } else { - to = DistanceUnit.parse((String) vTo, unit, DistanceUnit.MILES); + to = DistanceUnit.parse((String) vTo, unit, DistanceUnit.DEFAULT); } - to = geoDistance.normalize(to, DistanceUnit.MILES); + to = geoDistance.normalize(to, DistanceUnit.DEFAULT); } if (normalizeLat || normalizeLon) { diff --git a/src/main/java/org/elasticsearch/index/query/GeoPolygonFilterBuilder.java b/src/main/java/org/elasticsearch/index/query/GeoPolygonFilterBuilder.java index 6239c0ffc8d2e..e32a1e58e1bed 100644 --- a/src/main/java/org/elasticsearch/index/query/GeoPolygonFilterBuilder.java +++ b/src/main/java/org/elasticsearch/index/query/GeoPolygonFilterBuilder.java @@ -32,9 +32,11 @@ */ public class GeoPolygonFilterBuilder extends BaseFilterBuilder { + public static final String POINTS = GeoPolygonFilterParser.POINTS; + private final String name; - private final List points = Lists.newArrayList(); + private final List shell = Lists.newArrayList(); private Boolean cache; private String cacheKey; @@ -53,15 +55,18 @@ public GeoPolygonFilterBuilder(String name) { * @return */ public GeoPolygonFilterBuilder addPoint(double lat, double lon) { - points.add(new GeoPoint(lat, lon)); - return this; + return addPoint(new GeoPoint(lat, lon)); } public GeoPolygonFilterBuilder addPoint(String geohash) { - points.add(GeoHashUtils.decode(geohash)); - return this; + return addPoint(GeoHashUtils.decode(geohash)); } + public GeoPolygonFilterBuilder addPoint(GeoPoint point) { + shell.add(point); + return this; + } + /** * Sets the filter name for the filter that can be used when searching for matched_filters per hit. */ @@ -88,8 +93,8 @@ protected void doXContent(XContentBuilder builder, Params params) throws IOExcep builder.startObject(GeoPolygonFilterParser.NAME); builder.startObject(name); - builder.startArray("points"); - for (GeoPoint point : points) { + builder.startArray(POINTS); + for (GeoPoint point : shell) { builder.startArray().value(point.lon()).value(point.lat()).endArray(); } builder.endArray(); diff --git a/src/main/java/org/elasticsearch/index/query/GeoPolygonFilterParser.java b/src/main/java/org/elasticsearch/index/query/GeoPolygonFilterParser.java index 37116cf64e8a2..4a5a9fc5a0e63 100644 --- a/src/main/java/org/elasticsearch/index/query/GeoPolygonFilterParser.java +++ b/src/main/java/org/elasticsearch/index/query/GeoPolygonFilterParser.java @@ -25,6 +25,7 @@ import org.elasticsearch.common.geo.GeoUtils; import org.elasticsearch.common.inject.Inject; import org.elasticsearch.common.xcontent.XContentParser; +import org.elasticsearch.common.xcontent.XContentParser.Token; import org.elasticsearch.index.cache.filter.support.CacheKeyFilter; import org.elasticsearch.index.fielddata.IndexGeoPointFieldData; import org.elasticsearch.index.mapper.FieldMapper; @@ -52,6 +53,7 @@ public class GeoPolygonFilterParser implements FilterParser { public static final String NAME = "geo_polygon"; + public static final String POINTS = "points"; @Inject public GeoPolygonFilterParser() { @@ -69,7 +71,8 @@ public Filter parse(QueryParseContext parseContext) throws IOException, QueryPar boolean cache = false; CacheKeyFilter.Key cacheKey = null; String fieldName = null; - List points = Lists.newArrayList(); + + List shell = Lists.newArrayList(); boolean normalizeLon = true; boolean normalizeLat = true; @@ -88,9 +91,9 @@ public Filter parse(QueryParseContext parseContext) throws IOException, QueryPar if (token == XContentParser.Token.FIELD_NAME) { currentFieldName = parser.currentName(); } else if (token == XContentParser.Token.START_ARRAY) { - if ("points".equals(currentFieldName)) { - while ((token = parser.nextToken()) != XContentParser.Token.END_ARRAY) { - points.add(GeoPoint.parse(parser)); + if(POINTS.equals(currentFieldName)) { + while((token = parser.nextToken()) != Token.END_ARRAY) { + shell.add(GeoPoint.parse(parser)); } } else { throw new QueryParsingException(parseContext.index(), "[geo_polygon] filter does not support [" + currentFieldName + "]"); @@ -113,12 +116,23 @@ public Filter parse(QueryParseContext parseContext) throws IOException, QueryPar } } - if (points.isEmpty()) { + if (shell.isEmpty()) { throw new QueryParsingException(parseContext.index(), "no points defined for geo_polygon filter"); + } else { + if(shell.size() < 3) { + throw new QueryParsingException(parseContext.index(), "to few points defined for geo_polygon filter"); + } + GeoPoint start = shell.get(0); + if(!start.equals(shell.get(shell.size()-1))) { + shell.add(start); + } + if(shell.size() < 4) { + throw new QueryParsingException(parseContext.index(), "to few points defined for geo_polygon filter"); + } } if (normalizeLat || normalizeLon) { - for (GeoPoint point : points) { + for (GeoPoint point : shell) { GeoUtils.normalizePoint(point, normalizeLat, normalizeLon); } } @@ -133,7 +147,7 @@ public Filter parse(QueryParseContext parseContext) throws IOException, QueryPar } IndexGeoPointFieldData indexFieldData = parseContext.fieldData().getForField(mapper); - Filter filter = new GeoPolygonFilter(points.toArray(new GeoPoint[points.size()]), indexFieldData); + Filter filter = new GeoPolygonFilter(indexFieldData, shell.toArray(new GeoPoint[shell.size()])); if (cache) { filter = parseContext.cacheFilter(filter, cacheKey); } diff --git a/src/main/java/org/elasticsearch/index/query/GeoShapeFilterParser.java b/src/main/java/org/elasticsearch/index/query/GeoShapeFilterParser.java index 67d0a3d1e224c..4f4f2a1fdf2d7 100644 --- a/src/main/java/org/elasticsearch/index/query/GeoShapeFilterParser.java +++ b/src/main/java/org/elasticsearch/index/query/GeoShapeFilterParser.java @@ -170,7 +170,6 @@ public Filter parse(QueryParseContext parseContext) throws IOException, QueryPar throw new QueryParsingException(parseContext.index(), "Field [" + fieldName + "] is not a geo_shape"); } - GeoShapeFieldMapper shapeFieldMapper = (GeoShapeFieldMapper) fieldMapper; PrefixTreeStrategy strategy = shapeFieldMapper.defaultStrategy(); if (strategyName != null) { diff --git a/src/main/java/org/elasticsearch/index/query/GeohashCellFilter.java b/src/main/java/org/elasticsearch/index/query/GeohashCellFilter.java index a32f2fe7c81f2..b41ba3be11131 100644 --- a/src/main/java/org/elasticsearch/index/query/GeohashCellFilter.java +++ b/src/main/java/org/elasticsearch/index/query/GeohashCellFilter.java @@ -140,7 +140,7 @@ public Builder precision(int levels) { } public Builder precision(String precision) { - double meters = DistanceUnit.parse(precision, DistanceUnit.METERS, DistanceUnit.METERS); + double meters = DistanceUnit.parse(precision, DistanceUnit.DEFAULT, DistanceUnit.METERS); return precision(GeoUtils.geoHashLevelsForPrecision(meters)); } @@ -203,7 +203,7 @@ public Filter parse(QueryParseContext parseContext) throws IOException, QueryPar if(token == Token.VALUE_NUMBER) { levels = parser.intValue(); } else if(token == Token.VALUE_STRING) { - double meters = DistanceUnit.parse(parser.text(), DistanceUnit.METERS, DistanceUnit.METERS); + double meters = DistanceUnit.parse(parser.text(), DistanceUnit.DEFAULT, DistanceUnit.METERS); levels = GeoUtils.geoHashLevelsForPrecision(meters); } } else if (NEIGHBORS.equals(field)) { diff --git a/src/main/java/org/elasticsearch/index/query/functionscore/DecayFunctionParser.java b/src/main/java/org/elasticsearch/index/query/functionscore/DecayFunctionParser.java index 00ca852945c1c..6321fe64a8bd3 100644 --- a/src/main/java/org/elasticsearch/index/query/functionscore/DecayFunctionParser.java +++ b/src/main/java/org/elasticsearch/index/query/functionscore/DecayFunctionParser.java @@ -218,8 +218,8 @@ private ScoreFunction parseGeoVariable(String fieldName, XContentParser parser, if (origin == null || scaleString == null) { throw new ElasticsearchParseException(DecayFunctionBuilder.ORIGIN + " and " + DecayFunctionBuilder.SCALE + " must be set for geo fields."); } - double scale = DistanceUnit.parse(scaleString, DistanceUnit.METERS, DistanceUnit.METERS); - double offset = DistanceUnit.parse(offsetString, DistanceUnit.METERS, DistanceUnit.METERS); + double scale = DistanceUnit.DEFAULT.parse(scaleString, DistanceUnit.DEFAULT); + double offset = DistanceUnit.DEFAULT.parse(offsetString, DistanceUnit.DEFAULT); IndexGeoPointFieldData indexFieldData = parseContext.fieldData().getForField(mapper); return new GeoFieldDataScoreFunction(origin, scale, decay, offset, getDecayFunction(), indexFieldData); diff --git a/src/main/java/org/elasticsearch/index/search/geo/GeoDistanceFilter.java b/src/main/java/org/elasticsearch/index/search/geo/GeoDistanceFilter.java index e66ccc1b7ba92..970499c802d02 100644 --- a/src/main/java/org/elasticsearch/index/search/geo/GeoDistanceFilter.java +++ b/src/main/java/org/elasticsearch/index/search/geo/GeoDistanceFilter.java @@ -63,9 +63,9 @@ public GeoDistanceFilter(double lat, double lon, double distance, GeoDistance ge this.geoDistance = geoDistance; this.indexFieldData = indexFieldData; - this.fixedSourceDistance = geoDistance.fixedSourceDistance(lat, lon, DistanceUnit.MILES); + this.fixedSourceDistance = geoDistance.fixedSourceDistance(lat, lon, DistanceUnit.DEFAULT); if (optimizeBbox != null && !"none".equals(optimizeBbox)) { - distanceBoundingCheck = GeoDistance.distanceBoundingCheck(lat, lon, distance, DistanceUnit.MILES); + distanceBoundingCheck = GeoDistance.distanceBoundingCheck(lat, lon, distance, DistanceUnit.DEFAULT); if ("memory".equals(optimizeBbox)) { boundingBoxFilter = null; } else if ("indexed".equals(optimizeBbox)) { diff --git a/src/main/java/org/elasticsearch/index/search/geo/GeoDistanceRangeFilter.java b/src/main/java/org/elasticsearch/index/search/geo/GeoDistanceRangeFilter.java index 82c990c80b6c0..7f0fe4acc1594 100644 --- a/src/main/java/org/elasticsearch/index/search/geo/GeoDistanceRangeFilter.java +++ b/src/main/java/org/elasticsearch/index/search/geo/GeoDistanceRangeFilter.java @@ -46,8 +46,8 @@ public class GeoDistanceRangeFilter extends Filter { private final double lat; private final double lon; - private final double inclusiveLowerPoint; // in miles - private final double inclusiveUpperPoint; // in miles + private final double inclusiveLowerPoint; // in meters + private final double inclusiveUpperPoint; // in meters private final GeoDistance geoDistance; private final GeoDistance.FixedSourceDistance fixedSourceDistance; @@ -63,7 +63,7 @@ public GeoDistanceRangeFilter(GeoPoint point, Double lowerVal, Double upperVal, this.geoDistance = geoDistance; this.indexFieldData = indexFieldData; - this.fixedSourceDistance = geoDistance.fixedSourceDistance(lat, lon, DistanceUnit.MILES); + this.fixedSourceDistance = geoDistance.fixedSourceDistance(lat, lon, DistanceUnit.DEFAULT); if (lowerVal != null) { double f = lowerVal.doubleValue(); @@ -85,7 +85,7 @@ public GeoDistanceRangeFilter(GeoPoint point, Double lowerVal, Double upperVal, } if (optimizeBbox != null && !"none".equals(optimizeBbox)) { - distanceBoundingCheck = GeoDistance.distanceBoundingCheck(lat, lon, inclusiveUpperPoint, DistanceUnit.MILES); + distanceBoundingCheck = GeoDistance.distanceBoundingCheck(lat, lon, inclusiveUpperPoint, DistanceUnit.DEFAULT); if ("memory".equals(optimizeBbox)) { boundingBoxFilter = null; } else if ("indexed".equals(optimizeBbox)) { diff --git a/src/main/java/org/elasticsearch/index/search/geo/GeoPolygonFilter.java b/src/main/java/org/elasticsearch/index/search/geo/GeoPolygonFilter.java index 1067f9b745335..23f0ce699a1b2 100644 --- a/src/main/java/org/elasticsearch/index/search/geo/GeoPolygonFilter.java +++ b/src/main/java/org/elasticsearch/index/search/geo/GeoPolygonFilter.java @@ -41,7 +41,7 @@ public class GeoPolygonFilter extends Filter { private final IndexGeoPointFieldData indexFieldData; - public GeoPolygonFilter(GeoPoint[] points, IndexGeoPointFieldData indexFieldData) { + public GeoPolygonFilter(IndexGeoPointFieldData indexFieldData, GeoPoint...points) { this.points = points; this.indexFieldData = indexFieldData; } @@ -62,7 +62,10 @@ public DocIdSet getDocIdSet(AtomicReaderContext context, Bits acceptedDocs) thro @Override public String toString() { - return "GeoPolygonFilter(" + indexFieldData.getFieldNames().indexName() + ", " + Arrays.toString(points) + ")"; + StringBuilder sb = new StringBuilder("GeoPolygonFilter("); + sb.append(indexFieldData.getFieldNames().indexName()); + sb.append(", ").append(Arrays.toString(points)).append(')'); + return sb.toString(); } public static class GeoPolygonDocIdSet extends MatchDocIdSet { @@ -93,19 +96,16 @@ protected boolean matchDoc(int doc) { } private static boolean pointInPolygon(GeoPoint[] points, double lat, double lon) { - int i; - int j = points.length - 1; boolean inPoly = false; - for (i = 0; i < points.length; i++) { - if (points[i].lon() < lon && points[j].lon() >= lon - || points[j].lon() < lon && points[i].lon() >= lon) { + for (int i = 1; i < points.length; i++) { + if (points[i].lon() < lon && points[i-1].lon() >= lon + || points[i-1].lon() < lon && points[i].lon() >= lon) { if (points[i].lat() + (lon - points[i].lon()) / - (points[j].lon() - points[i].lon()) * (points[j].lat() - points[i].lat()) < lat) { + (points[i-1].lon() - points[i].lon()) * (points[i-1].lat() - points[i].lat()) < lat) { inPoly = !inPoly; } } - j = i; } return inPoly; } diff --git a/src/main/java/org/elasticsearch/index/search/geo/IndexedGeoBoundingBoxFilter.java b/src/main/java/org/elasticsearch/index/search/geo/IndexedGeoBoundingBoxFilter.java index a388693b4a3a0..cac948f92f3b0 100644 --- a/src/main/java/org/elasticsearch/index/search/geo/IndexedGeoBoundingBoxFilter.java +++ b/src/main/java/org/elasticsearch/index/search/geo/IndexedGeoBoundingBoxFilter.java @@ -41,19 +41,19 @@ public static Filter create(GeoPoint topLeft, GeoPoint bottomRight, GeoPointFiel } //checks to see if bounding box crosses 180 degrees if (topLeft.lon() > bottomRight.lon()) { - return new LeftGeoBoundingBoxFilter(topLeft, bottomRight, fieldMapper); + return new WestGeoBoundingBoxFilter(topLeft, bottomRight, fieldMapper); } else { - return new RightGeoBoundingBoxFilter(topLeft, bottomRight, fieldMapper); + return new EastGeoBoundingBoxFilter(topLeft, bottomRight, fieldMapper); } } - static class LeftGeoBoundingBoxFilter extends Filter { + static class WestGeoBoundingBoxFilter extends Filter { final Filter lonFilter1; final Filter lonFilter2; final Filter latFilter; - public LeftGeoBoundingBoxFilter(GeoPoint topLeft, GeoPoint bottomRight, GeoPointFieldMapper fieldMapper) { + public WestGeoBoundingBoxFilter(GeoPoint topLeft, GeoPoint bottomRight, GeoPointFieldMapper fieldMapper) { lonFilter1 = fieldMapper.lonMapper().rangeFilter(null, bottomRight.lon(), true, true); lonFilter2 = fieldMapper.lonMapper().rangeFilter(topLeft.lon(), null, true, true); latFilter = fieldMapper.latMapper().rangeFilter(bottomRight.lat(), topLeft.lat(), true, true); @@ -97,7 +97,7 @@ public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; - LeftGeoBoundingBoxFilter that = (LeftGeoBoundingBoxFilter) o; + WestGeoBoundingBoxFilter that = (WestGeoBoundingBoxFilter) o; if (latFilter != null ? !latFilter.equals(that.latFilter) : that.latFilter != null) return false; if (lonFilter1 != null ? !lonFilter1.equals(that.lonFilter1) : that.lonFilter1 != null) return false; @@ -115,12 +115,12 @@ public int hashCode() { } } - static class RightGeoBoundingBoxFilter extends Filter { + static class EastGeoBoundingBoxFilter extends Filter { final Filter lonFilter; final Filter latFilter; - public RightGeoBoundingBoxFilter(GeoPoint topLeft, GeoPoint bottomRight, GeoPointFieldMapper fieldMapper) { + public EastGeoBoundingBoxFilter(GeoPoint topLeft, GeoPoint bottomRight, GeoPointFieldMapper fieldMapper) { lonFilter = fieldMapper.lonMapper().rangeFilter(topLeft.lon(), bottomRight.lon(), true, true); latFilter = fieldMapper.latMapper().rangeFilter(bottomRight.lat(), topLeft.lat(), true, true); } @@ -146,7 +146,7 @@ public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; - RightGeoBoundingBoxFilter that = (RightGeoBoundingBoxFilter) o; + EastGeoBoundingBoxFilter that = (EastGeoBoundingBoxFilter) o; if (latFilter != null ? !latFilter.equals(that.latFilter) : that.latFilter != null) return false; if (lonFilter != null ? !lonFilter.equals(that.lonFilter) : that.lonFilter != null) return false; diff --git a/src/main/java/org/elasticsearch/search/aggregations/bucket/range/geodistance/GeoDistanceParser.java b/src/main/java/org/elasticsearch/search/aggregations/bucket/range/geodistance/GeoDistanceParser.java index 7b9eac6575ed2..6e76ccbff8744 100644 --- a/src/main/java/org/elasticsearch/search/aggregations/bucket/range/geodistance/GeoDistanceParser.java +++ b/src/main/java/org/elasticsearch/search/aggregations/bucket/range/geodistance/GeoDistanceParser.java @@ -66,7 +66,7 @@ public AggregatorFactory parse(String aggregationName, XContentParser parser, Se String field = null; List ranges = null; GeoPoint origin = null; - DistanceUnit unit = DistanceUnit.KILOMETERS; + DistanceUnit unit = DistanceUnit.DEFAULT; GeoDistance distanceType = GeoDistance.DEFAULT; boolean keyed = false; diff --git a/src/main/java/org/elasticsearch/search/facet/geodistance/GeoDistanceFacetParser.java b/src/main/java/org/elasticsearch/search/facet/geodistance/GeoDistanceFacetParser.java index bc639b37ab707..4cbcbbe52bace 100644 --- a/src/main/java/org/elasticsearch/search/facet/geodistance/GeoDistanceFacetParser.java +++ b/src/main/java/org/elasticsearch/search/facet/geodistance/GeoDistanceFacetParser.java @@ -73,7 +73,7 @@ public FacetExecutor parse(String facetName, XContentParser parser, SearchContex String scriptLang = null; Map params = null; GeoPoint point = new GeoPoint(); - DistanceUnit unit = DistanceUnit.KILOMETERS; + DistanceUnit unit = DistanceUnit.DEFAULT; GeoDistance geoDistance = GeoDistance.DEFAULT; List entries = Lists.newArrayList(); diff --git a/src/main/java/org/elasticsearch/search/sort/GeoDistanceSortParser.java b/src/main/java/org/elasticsearch/search/sort/GeoDistanceSortParser.java index c1c74e7f17a83..49b1d8af13f21 100644 --- a/src/main/java/org/elasticsearch/search/sort/GeoDistanceSortParser.java +++ b/src/main/java/org/elasticsearch/search/sort/GeoDistanceSortParser.java @@ -53,7 +53,7 @@ public String[] names() { public SortField parse(XContentParser parser, SearchContext context) throws Exception { String fieldName = null; GeoPoint point = new GeoPoint(); - DistanceUnit unit = DistanceUnit.KILOMETERS; + DistanceUnit unit = DistanceUnit.DEFAULT; GeoDistance geoDistance = GeoDistance.DEFAULT; boolean reverse = false; SortMode sortMode = null; diff --git a/src/test/java/org/elasticsearch/common/unit/DistanceUnitTests.java b/src/test/java/org/elasticsearch/common/unit/DistanceUnitTests.java index 642d9ffb0ed4e..d84107eb7f3c6 100644 --- a/src/test/java/org/elasticsearch/common/unit/DistanceUnitTests.java +++ b/src/test/java/org/elasticsearch/common/unit/DistanceUnitTests.java @@ -22,7 +22,6 @@ import org.elasticsearch.test.ElasticsearchTestCase; import org.junit.Test; -import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.closeTo; import static org.hamcrest.Matchers.equalTo; @@ -33,30 +32,30 @@ public class DistanceUnitTests extends ElasticsearchTestCase { @Test public void testSimpleDistanceUnit() { - assertThat(DistanceUnit.MILES.toKilometers(10), closeTo(16.09344, 0.001)); - assertThat(DistanceUnit.MILES.toMiles(10), closeTo(10, 0.001)); - assertThat(DistanceUnit.KILOMETERS.toMiles(10), closeTo(6.21371192, 0.001)); - assertThat(DistanceUnit.KILOMETERS.toKilometers(10), closeTo(10, 0.001)); - assertThat(DistanceUnit.METERS.toKilometers(10), closeTo(0.01, 0.00001)); - assertThat(DistanceUnit.METERS.toKilometers(1000), closeTo(1, 0.001)); - assertThat(DistanceUnit.KILOMETERS.toMeters(1), closeTo(1000, 0.001)); + assertThat(DistanceUnit.KILOMETERS.convert(10, DistanceUnit.MILES), closeTo(16.09344, 0.001)); + assertThat(DistanceUnit.MILES.convert(10, DistanceUnit.MILES), closeTo(10, 0.001)); + assertThat(DistanceUnit.MILES.convert(10, DistanceUnit.KILOMETERS), closeTo(6.21371192, 0.001)); + assertThat(DistanceUnit.KILOMETERS.convert(10, DistanceUnit.KILOMETERS), closeTo(10, 0.001)); + assertThat(DistanceUnit.KILOMETERS.convert(10, DistanceUnit.METERS), closeTo(0.01, 0.00001)); + assertThat(DistanceUnit.KILOMETERS.convert(1000,DistanceUnit.METERS), closeTo(1, 0.001)); + assertThat(DistanceUnit.METERS.convert(1, DistanceUnit.KILOMETERS), closeTo(1000, 0.001)); } @Test public void testDistanceUnitParsing() { - assertThat(DistanceUnit.Distance.parseDistance("50km", null).unit, equalTo(DistanceUnit.KILOMETERS)); - assertThat(DistanceUnit.Distance.parseDistance("500m", null).unit, equalTo(DistanceUnit.METERS)); - assertThat(DistanceUnit.Distance.parseDistance("51mi", null).unit, equalTo(DistanceUnit.MILES)); - assertThat(DistanceUnit.Distance.parseDistance("52yd", null).unit, equalTo(DistanceUnit.YARD)); - assertThat(DistanceUnit.Distance.parseDistance("12in", null).unit, equalTo(DistanceUnit.INCH)); - assertThat(DistanceUnit.Distance.parseDistance("23mm", null).unit, equalTo(DistanceUnit.MILLIMETERS)); - assertThat(DistanceUnit.Distance.parseDistance("23cm", null).unit, equalTo(DistanceUnit.CENTIMETERS)); + assertThat(DistanceUnit.Distance.parseDistance("50km").unit, equalTo(DistanceUnit.KILOMETERS)); + assertThat(DistanceUnit.Distance.parseDistance("500m").unit, equalTo(DistanceUnit.METERS)); + assertThat(DistanceUnit.Distance.parseDistance("51mi").unit, equalTo(DistanceUnit.MILES)); + assertThat(DistanceUnit.Distance.parseDistance("52yd").unit, equalTo(DistanceUnit.YARD)); + assertThat(DistanceUnit.Distance.parseDistance("12in").unit, equalTo(DistanceUnit.INCH)); + assertThat(DistanceUnit.Distance.parseDistance("23mm").unit, equalTo(DistanceUnit.MILLIMETERS)); + assertThat(DistanceUnit.Distance.parseDistance("23cm").unit, equalTo(DistanceUnit.CENTIMETERS)); double testValue = 12345.678; for (DistanceUnit unit : DistanceUnit.values()) { assertThat("Unit can be parsed from '" + unit.toString() + "'", DistanceUnit.fromString(unit.toString()), equalTo(unit)); assertThat("Unit can be parsed from '" + testValue + unit.toString() + "'", DistanceUnit.fromString(unit.toString()), equalTo(unit)); - assertThat("Value can be parsed from '" + testValue + unit.toString() + "'", DistanceUnit.Distance.parseDistance(unit.toString(testValue), null).value, equalTo(testValue)); + assertThat("Value can be parsed from '" + testValue + unit.toString() + "'", DistanceUnit.Distance.parseDistance(unit.toString(testValue)).value, equalTo(testValue)); } } diff --git a/src/test/java/org/elasticsearch/index/mapper/geo/GeoMappingTests.java b/src/test/java/org/elasticsearch/index/mapper/geo/GeoMappingTests.java index 2f9c92e9cbb3a..5002289bc5dbc 100644 --- a/src/test/java/org/elasticsearch/index/mapper/geo/GeoMappingTests.java +++ b/src/test/java/org/elasticsearch/index/mapper/geo/GeoMappingTests.java @@ -71,7 +71,7 @@ private void assertPrecision(Distance expected) throws Exception { Map properties = (Map) mappings.get("test").get("type1").getSourceAsMap().get("properties"); Map pinProperties = (Map) properties.get("pin"); Map pinFieldData = (Map) pinProperties.get("fielddata"); - Distance precision = Distance.parseDistance(pinFieldData.get("precision").toString(), DistanceUnit.METERS); + Distance precision = Distance.parseDistance(pinFieldData.get("precision").toString()); assertEquals(expected, precision); } diff --git a/src/test/java/org/elasticsearch/index/query/SimpleIndexQueryParserTests.java b/src/test/java/org/elasticsearch/index/query/SimpleIndexQueryParserTests.java index 7da272676bade..9f8715e77ed3e 100644 --- a/src/test/java/org/elasticsearch/index/query/SimpleIndexQueryParserTests.java +++ b/src/test/java/org/elasticsearch/index/query/SimpleIndexQueryParserTests.java @@ -43,6 +43,7 @@ import org.elasticsearch.common.settings.ImmutableSettings; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.common.settings.SettingsModule; +import org.elasticsearch.common.unit.DistanceUnit; import org.elasticsearch.common.unit.Fuzziness; import org.elasticsearch.index.Index; import org.elasticsearch.index.IndexNameModule; @@ -60,10 +61,10 @@ import org.elasticsearch.index.search.geo.InMemoryGeoBoundingBoxFilter; import org.elasticsearch.index.settings.IndexSettingsModule; import org.elasticsearch.index.similarity.SimilarityModule; -import org.elasticsearch.indices.query.IndicesQueriesModule; -import org.elasticsearch.script.ScriptModule; import org.elasticsearch.indices.fielddata.breaker.CircuitBreakerService; import org.elasticsearch.indices.fielddata.breaker.DummyCircuitBreakerService; +import org.elasticsearch.indices.query.IndicesQueriesModule; +import org.elasticsearch.script.ScriptModule; import org.elasticsearch.test.ElasticsearchTestCase; import org.elasticsearch.threadpool.ThreadPool; import org.elasticsearch.threadpool.ThreadPoolModule; @@ -1768,7 +1769,7 @@ public void testGeoDistanceFilterNamed() throws IOException { assertThat(filter.fieldName(), equalTo("location")); assertThat(filter.lat(), closeTo(40, 0.00001)); assertThat(filter.lon(), closeTo(-70, 0.00001)); - assertThat(filter.distance(), closeTo(12, 0.00001)); + assertThat(filter.distance(), closeTo(DistanceUnit.DEFAULT.convert(12, DistanceUnit.MILES), 0.00001)); } @Test @@ -1782,7 +1783,7 @@ public void testGeoDistanceFilter1() throws IOException { assertThat(filter.fieldName(), equalTo("location")); assertThat(filter.lat(), closeTo(40, 0.00001)); assertThat(filter.lon(), closeTo(-70, 0.00001)); - assertThat(filter.distance(), closeTo(12, 0.00001)); + assertThat(filter.distance(), closeTo(DistanceUnit.DEFAULT.convert(12, DistanceUnit.MILES), 0.00001)); } @Test @@ -1796,7 +1797,7 @@ public void testGeoDistanceFilter2() throws IOException { assertThat(filter.fieldName(), equalTo("location")); assertThat(filter.lat(), closeTo(40, 0.00001)); assertThat(filter.lon(), closeTo(-70, 0.00001)); - assertThat(filter.distance(), closeTo(12, 0.00001)); + assertThat(filter.distance(), closeTo(DistanceUnit.DEFAULT.convert(12, DistanceUnit.MILES), 0.00001)); } @Test @@ -1810,7 +1811,7 @@ public void testGeoDistanceFilter3() throws IOException { assertThat(filter.fieldName(), equalTo("location")); assertThat(filter.lat(), closeTo(40, 0.00001)); assertThat(filter.lon(), closeTo(-70, 0.00001)); - assertThat(filter.distance(), closeTo(12, 0.00001)); + assertThat(filter.distance(), closeTo(DistanceUnit.DEFAULT.convert(12, DistanceUnit.MILES), 0.00001)); } @Test @@ -1824,7 +1825,7 @@ public void testGeoDistanceFilter4() throws IOException { assertThat(filter.fieldName(), equalTo("location")); assertThat(filter.lat(), closeTo(40, 0.00001)); assertThat(filter.lon(), closeTo(-70, 0.00001)); - assertThat(filter.distance(), closeTo(12, 0.00001)); + assertThat(filter.distance(), closeTo(DistanceUnit.DEFAULT.convert(12, DistanceUnit.MILES), 0.00001)); } @Test @@ -1838,7 +1839,7 @@ public void testGeoDistanceFilter5() throws IOException { assertThat(filter.fieldName(), equalTo("location")); assertThat(filter.lat(), closeTo(40, 0.00001)); assertThat(filter.lon(), closeTo(-70, 0.00001)); - assertThat(filter.distance(), closeTo(12, 0.00001)); + assertThat(filter.distance(), closeTo(DistanceUnit.DEFAULT.convert(12, DistanceUnit.MILES), 0.00001)); } @Test @@ -1852,7 +1853,7 @@ public void testGeoDistanceFilter6() throws IOException { assertThat(filter.fieldName(), equalTo("location")); assertThat(filter.lat(), closeTo(40, 0.00001)); assertThat(filter.lon(), closeTo(-70, 0.00001)); - assertThat(filter.distance(), closeTo(12, 0.00001)); + assertThat(filter.distance(), closeTo(DistanceUnit.DEFAULT.convert(12, DistanceUnit.MILES), 0.00001)); } @Test @@ -1866,7 +1867,7 @@ public void testGeoDistanceFilter7() throws IOException { assertThat(filter.fieldName(), equalTo("location")); assertThat(filter.lat(), closeTo(40, 0.00001)); assertThat(filter.lon(), closeTo(-70, 0.00001)); - assertThat(filter.distance(), closeTo(12, 0.00001)); + assertThat(filter.distance(), closeTo(DistanceUnit.DEFAULT.convert(0.012, DistanceUnit.MILES), 0.00001)); } @Test @@ -1880,7 +1881,7 @@ public void testGeoDistanceFilter8() throws IOException { assertThat(filter.fieldName(), equalTo("location")); assertThat(filter.lat(), closeTo(40, 0.00001)); assertThat(filter.lon(), closeTo(-70, 0.00001)); - assertThat(filter.distance(), closeTo(12, 0.00001)); + assertThat(filter.distance(), closeTo(DistanceUnit.KILOMETERS.convert(12, DistanceUnit.MILES), 0.00001)); } @Test @@ -1894,7 +1895,7 @@ public void testGeoDistanceFilter9() throws IOException { assertThat(filter.fieldName(), equalTo("location")); assertThat(filter.lat(), closeTo(40, 0.00001)); assertThat(filter.lon(), closeTo(-70, 0.00001)); - assertThat(filter.distance(), closeTo(12, 0.00001)); + assertThat(filter.distance(), closeTo(DistanceUnit.DEFAULT.convert(12, DistanceUnit.MILES), 0.00001)); } @Test @@ -1908,7 +1909,7 @@ public void testGeoDistanceFilter10() throws IOException { assertThat(filter.fieldName(), equalTo("location")); assertThat(filter.lat(), closeTo(40, 0.00001)); assertThat(filter.lon(), closeTo(-70, 0.00001)); - assertThat(filter.distance(), closeTo(12, 0.00001)); + assertThat(filter.distance(), closeTo(DistanceUnit.DEFAULT.convert(12, DistanceUnit.MILES), 0.00001)); } @Test @@ -1922,7 +1923,7 @@ public void testGeoDistanceFilter11() throws IOException { assertThat(filter.fieldName(), equalTo("location")); assertThat(filter.lat(), closeTo(40, 0.00001)); assertThat(filter.lon(), closeTo(-70, 0.00001)); - assertThat(filter.distance(), closeTo(12, 0.00001)); + assertThat(filter.distance(), closeTo(DistanceUnit.DEFAULT.convert(12, DistanceUnit.MILES), 0.00001)); } @Test @@ -1936,7 +1937,7 @@ public void testGeoDistanceFilter12() throws IOException { assertThat(filter.fieldName(), equalTo("location")); assertThat(filter.lat(), closeTo(40, 0.00001)); assertThat(filter.lon(), closeTo(-70, 0.00001)); - assertThat(filter.distance(), closeTo(12, 0.00001)); + assertThat(filter.distance(), closeTo(DistanceUnit.DEFAULT.convert(12, DistanceUnit.MILES), 0.00001)); } @Test @@ -2016,6 +2017,37 @@ public void testGeoBoundingBoxFilter4() throws IOException { assertThat(filter.bottomRight().lon(), closeTo(-80, 0.00001)); } + @Test + public void testGeoBoundingBoxFilter5() throws IOException { + IndexQueryParserService queryParser = queryParser(); + String query = copyToStringFromClasspath("/org/elasticsearch/index/query/geo_boundingbox5.json"); + Query parsedQuery = queryParser.parse(query).query(); + assertThat(parsedQuery, instanceOf(XConstantScoreQuery.class)); + XConstantScoreQuery constantScoreQuery = (XConstantScoreQuery) parsedQuery; + InMemoryGeoBoundingBoxFilter filter = (InMemoryGeoBoundingBoxFilter) constantScoreQuery.getFilter(); + assertThat(filter.fieldName(), equalTo("location")); + assertThat(filter.topLeft().lat(), closeTo(40, 0.00001)); + assertThat(filter.topLeft().lon(), closeTo(-70, 0.00001)); + assertThat(filter.bottomRight().lat(), closeTo(30, 0.00001)); + assertThat(filter.bottomRight().lon(), closeTo(-80, 0.00001)); + } + + @Test + public void testGeoBoundingBoxFilter6() throws IOException { + IndexQueryParserService queryParser = queryParser(); + String query = copyToStringFromClasspath("/org/elasticsearch/index/query/geo_boundingbox6.json"); + Query parsedQuery = queryParser.parse(query).query(); + assertThat(parsedQuery, instanceOf(XConstantScoreQuery.class)); + XConstantScoreQuery constantScoreQuery = (XConstantScoreQuery) parsedQuery; + InMemoryGeoBoundingBoxFilter filter = (InMemoryGeoBoundingBoxFilter) constantScoreQuery.getFilter(); + assertThat(filter.fieldName(), equalTo("location")); + assertThat(filter.topLeft().lat(), closeTo(40, 0.00001)); + assertThat(filter.topLeft().lon(), closeTo(-70, 0.00001)); + assertThat(filter.bottomRight().lat(), closeTo(30, 0.00001)); + assertThat(filter.bottomRight().lon(), closeTo(-80, 0.00001)); + } + + @Test public void testGeoPolygonNamedFilter() throws IOException { IndexQueryParserService queryParser = queryParser(); @@ -2026,7 +2058,7 @@ public void testGeoPolygonNamedFilter() throws IOException { XConstantScoreQuery constantScoreQuery = (XConstantScoreQuery) parsedQuery.query(); GeoPolygonFilter filter = (GeoPolygonFilter) constantScoreQuery.getFilter(); assertThat(filter.fieldName(), equalTo("location")); - assertThat(filter.points().length, equalTo(3)); + assertThat(filter.points().length, equalTo(4)); assertThat(filter.points()[0].lat(), closeTo(40, 0.00001)); assertThat(filter.points()[0].lon(), closeTo(-70, 0.00001)); assertThat(filter.points()[1].lat(), closeTo(30, 0.00001)); @@ -2044,7 +2076,7 @@ public void testGeoPolygonFilter1() throws IOException { XConstantScoreQuery constantScoreQuery = (XConstantScoreQuery) parsedQuery; GeoPolygonFilter filter = (GeoPolygonFilter) constantScoreQuery.getFilter(); assertThat(filter.fieldName(), equalTo("location")); - assertThat(filter.points().length, equalTo(3)); + assertThat(filter.points().length, equalTo(4)); assertThat(filter.points()[0].lat(), closeTo(40, 0.00001)); assertThat(filter.points()[0].lon(), closeTo(-70, 0.00001)); assertThat(filter.points()[1].lat(), closeTo(30, 0.00001)); @@ -2062,7 +2094,7 @@ public void testGeoPolygonFilter2() throws IOException { XConstantScoreQuery constantScoreQuery = (XConstantScoreQuery) parsedQuery; GeoPolygonFilter filter = (GeoPolygonFilter) constantScoreQuery.getFilter(); assertThat(filter.fieldName(), equalTo("location")); - assertThat(filter.points().length, equalTo(3)); + assertThat(filter.points().length, equalTo(4)); assertThat(filter.points()[0].lat(), closeTo(40, 0.00001)); assertThat(filter.points()[0].lon(), closeTo(-70, 0.00001)); assertThat(filter.points()[1].lat(), closeTo(30, 0.00001)); @@ -2080,7 +2112,7 @@ public void testGeoPolygonFilter3() throws IOException { XConstantScoreQuery constantScoreQuery = (XConstantScoreQuery) parsedQuery; GeoPolygonFilter filter = (GeoPolygonFilter) constantScoreQuery.getFilter(); assertThat(filter.fieldName(), equalTo("location")); - assertThat(filter.points().length, equalTo(3)); + assertThat(filter.points().length, equalTo(4)); assertThat(filter.points()[0].lat(), closeTo(40, 0.00001)); assertThat(filter.points()[0].lon(), closeTo(-70, 0.00001)); assertThat(filter.points()[1].lat(), closeTo(30, 0.00001)); @@ -2098,7 +2130,7 @@ public void testGeoPolygonFilter4() throws IOException { XConstantScoreQuery constantScoreQuery = (XConstantScoreQuery) parsedQuery; GeoPolygonFilter filter = (GeoPolygonFilter) constantScoreQuery.getFilter(); assertThat(filter.fieldName(), equalTo("location")); - assertThat(filter.points().length, equalTo(3)); + assertThat(filter.points().length, equalTo(4)); assertThat(filter.points()[0].lat(), closeTo(40, 0.00001)); assertThat(filter.points()[0].lon(), closeTo(-70, 0.00001)); assertThat(filter.points()[1].lat(), closeTo(30, 0.00001)); diff --git a/src/test/java/org/elasticsearch/index/query/geo_boundingbox5.json b/src/test/java/org/elasticsearch/index/query/geo_boundingbox5.json new file mode 100644 index 0000000000000..347a463f0add2 --- /dev/null +++ b/src/test/java/org/elasticsearch/index/query/geo_boundingbox5.json @@ -0,0 +1,15 @@ +{ + "filtered":{ + "query":{ + "match_all":{} + }, + "filter":{ + "geo_bounding_box":{ + "location":{ + "top_right":"40, -80", + "bottom_left":"30, -70" + } + } + } + } +} diff --git a/src/test/java/org/elasticsearch/index/query/geo_boundingbox6.json b/src/test/java/org/elasticsearch/index/query/geo_boundingbox6.json new file mode 100644 index 0000000000000..96ccbd0268d3b --- /dev/null +++ b/src/test/java/org/elasticsearch/index/query/geo_boundingbox6.json @@ -0,0 +1,17 @@ +{ + "filtered":{ + "query":{ + "match_all":{} + }, + "filter":{ + "geo_bounding_box":{ + "location":{ + "right": -80, + "top": 40, + "left": -70, + "bottom": 30 + } + } + } + } +} diff --git a/src/test/java/org/elasticsearch/search/geo/GeoDistanceTests.java b/src/test/java/org/elasticsearch/search/geo/GeoDistanceTests.java index ac910b076955e..f82f8c42c24a8 100644 --- a/src/test/java/org/elasticsearch/search/geo/GeoDistanceTests.java +++ b/src/test/java/org/elasticsearch/search/geo/GeoDistanceTests.java @@ -262,10 +262,10 @@ public void testDistanceSortingMVFields() throws Exception { assertHitCount(searchResponse, 4); assertOrderedSearchHits(searchResponse, "1", "2", "3", "4"); - assertThat(((Number) searchResponse.getHits().getAt(0).sortValues()[0]).doubleValue(), closeTo(0d, 0.01d)); - assertThat(((Number) searchResponse.getHits().getAt(1).sortValues()[0]).doubleValue(), closeTo(0.4621d, 0.01d)); - assertThat(((Number) searchResponse.getHits().getAt(2).sortValues()[0]).doubleValue(), closeTo(1.055d, 0.01d)); - assertThat(((Number) searchResponse.getHits().getAt(3).sortValues()[0]).doubleValue(), closeTo(2.029d, 0.01d)); + assertThat(((Number) searchResponse.getHits().getAt(0).sortValues()[0]).doubleValue(), closeTo(0d, 10d)); + assertThat(((Number) searchResponse.getHits().getAt(1).sortValues()[0]).doubleValue(), closeTo(462.1d, 10d)); + assertThat(((Number) searchResponse.getHits().getAt(2).sortValues()[0]).doubleValue(), closeTo(1055.0d, 10d)); + assertThat(((Number) searchResponse.getHits().getAt(3).sortValues()[0]).doubleValue(), closeTo(2029.0d, 10d)); // Order: Asc, Mode: max searchResponse = client().prepareSearch("test").setQuery(matchAllQuery()) @@ -274,10 +274,10 @@ public void testDistanceSortingMVFields() throws Exception { assertHitCount(searchResponse, 4); assertOrderedSearchHits(searchResponse, "1", "3", "2", "4"); - assertThat(((Number) searchResponse.getHits().getAt(0).sortValues()[0]).doubleValue(), closeTo(0d, 0.01d)); - assertThat(((Number) searchResponse.getHits().getAt(1).sortValues()[0]).doubleValue(), closeTo(1.258d, 0.01d)); - assertThat(((Number) searchResponse.getHits().getAt(2).sortValues()[0]).doubleValue(), closeTo(5.286d, 0.01d)); - assertThat(((Number) searchResponse.getHits().getAt(3).sortValues()[0]).doubleValue(), closeTo(8.572d, 0.01d)); + assertThat(((Number) searchResponse.getHits().getAt(0).sortValues()[0]).doubleValue(), closeTo(0d, 10d)); + assertThat(((Number) searchResponse.getHits().getAt(1).sortValues()[0]).doubleValue(), closeTo(1258.0d, 10d)); + assertThat(((Number) searchResponse.getHits().getAt(2).sortValues()[0]).doubleValue(), closeTo(5286.0d, 10d)); + assertThat(((Number) searchResponse.getHits().getAt(3).sortValues()[0]).doubleValue(), closeTo(8572.0d, 10d)); // Order: Desc searchResponse = client().prepareSearch("test").setQuery(matchAllQuery()) @@ -286,10 +286,10 @@ public void testDistanceSortingMVFields() throws Exception { assertHitCount(searchResponse, 4); assertOrderedSearchHits(searchResponse, "4", "2", "3", "1"); - assertThat(((Number) searchResponse.getHits().getAt(0).sortValues()[0]).doubleValue(), closeTo(8.572d, 0.01d)); - assertThat(((Number) searchResponse.getHits().getAt(1).sortValues()[0]).doubleValue(), closeTo(5.286d, 0.01d)); - assertThat(((Number) searchResponse.getHits().getAt(2).sortValues()[0]).doubleValue(), closeTo(1.258d, 0.01d)); - assertThat(((Number) searchResponse.getHits().getAt(3).sortValues()[0]).doubleValue(), closeTo(0d, 0.01d)); + assertThat(((Number) searchResponse.getHits().getAt(0).sortValues()[0]).doubleValue(), closeTo(8572.0d, 10d)); + assertThat(((Number) searchResponse.getHits().getAt(1).sortValues()[0]).doubleValue(), closeTo(5286.0d, 10d)); + assertThat(((Number) searchResponse.getHits().getAt(2).sortValues()[0]).doubleValue(), closeTo(1258.0d, 10d)); + assertThat(((Number) searchResponse.getHits().getAt(3).sortValues()[0]).doubleValue(), closeTo(0d, 10d)); // Order: Desc, Mode: min searchResponse = client().prepareSearch("test").setQuery(matchAllQuery()) @@ -298,10 +298,10 @@ public void testDistanceSortingMVFields() throws Exception { assertHitCount(searchResponse, 4); assertOrderedSearchHits(searchResponse, "4", "3", "2", "1"); - assertThat(((Number) searchResponse.getHits().getAt(0).sortValues()[0]).doubleValue(), closeTo(2.029d, 0.01d)); - assertThat(((Number) searchResponse.getHits().getAt(1).sortValues()[0]).doubleValue(), closeTo(1.055d, 0.01d)); - assertThat(((Number) searchResponse.getHits().getAt(2).sortValues()[0]).doubleValue(), closeTo(0.4621d, 0.01d)); - assertThat(((Number) searchResponse.getHits().getAt(3).sortValues()[0]).doubleValue(), closeTo(0d, 0.01d)); + assertThat(((Number) searchResponse.getHits().getAt(0).sortValues()[0]).doubleValue(), closeTo(2029.0d, 10d)); + assertThat(((Number) searchResponse.getHits().getAt(1).sortValues()[0]).doubleValue(), closeTo(1055.0d, 10d)); + assertThat(((Number) searchResponse.getHits().getAt(2).sortValues()[0]).doubleValue(), closeTo(462.1d, 10d)); + assertThat(((Number) searchResponse.getHits().getAt(3).sortValues()[0]).doubleValue(), closeTo(0d, 10d)); searchResponse = client().prepareSearch("test").setQuery(matchAllQuery()) .addSort(SortBuilders.geoDistanceSort("locations").point(40.7143528, -74.0059731).sortMode("avg").order(SortOrder.ASC)) @@ -309,21 +309,21 @@ public void testDistanceSortingMVFields() throws Exception { assertHitCount(searchResponse, 4); assertOrderedSearchHits(searchResponse, "1", "3", "2", "4"); - assertThat(((Number) searchResponse.getHits().getAt(0).sortValues()[0]).doubleValue(), closeTo(0d, 0.01d)); - assertThat(((Number) searchResponse.getHits().getAt(1).sortValues()[0]).doubleValue(), closeTo(1.157d, 0.01d)); - assertThat(((Number) searchResponse.getHits().getAt(2).sortValues()[0]).doubleValue(), closeTo(2.874d, 0.01d)); - assertThat(((Number) searchResponse.getHits().getAt(3).sortValues()[0]).doubleValue(), closeTo(5.301d, 0.01d)); + assertThat(((Number) searchResponse.getHits().getAt(0).sortValues()[0]).doubleValue(), closeTo(0d, 10d)); + assertThat(((Number) searchResponse.getHits().getAt(1).sortValues()[0]).doubleValue(), closeTo(1157d, 10d)); + assertThat(((Number) searchResponse.getHits().getAt(2).sortValues()[0]).doubleValue(), closeTo(2874d, 10d)); + assertThat(((Number) searchResponse.getHits().getAt(3).sortValues()[0]).doubleValue(), closeTo(5301d, 10d)); searchResponse = client().prepareSearch("test").setQuery(matchAllQuery()) .addSort(SortBuilders.geoDistanceSort("locations").point(40.7143528, -74.0059731).sortMode("avg").order(SortOrder.DESC)) .execute().actionGet(); assertHitCount(searchResponse, 4); - assertOrderedSearchHits(searchResponse, "4", "2", "3", "1"); - assertThat(((Number) searchResponse.getHits().getAt(0).sortValues()[0]).doubleValue(), closeTo(5.301d, 0.01d)); - assertThat(((Number) searchResponse.getHits().getAt(1).sortValues()[0]).doubleValue(), closeTo(2.874d, 0.01d)); - assertThat(((Number) searchResponse.getHits().getAt(2).sortValues()[0]).doubleValue(), closeTo(1.157d, 0.01d)); - assertThat(((Number) searchResponse.getHits().getAt(3).sortValues()[0]).doubleValue(), closeTo(0d, 0.01d)); + assertOrderedSearchHits(searchResponse, "4", "2", "3", "1"); + assertThat(((Number) searchResponse.getHits().getAt(0).sortValues()[0]).doubleValue(), closeTo(5301.0d, 10d)); + assertThat(((Number) searchResponse.getHits().getAt(1).sortValues()[0]).doubleValue(), closeTo(2874.0d, 10d)); + assertThat(((Number) searchResponse.getHits().getAt(2).sortValues()[0]).doubleValue(), closeTo(1157.0d, 10d)); + assertThat(((Number) searchResponse.getHits().getAt(3).sortValues()[0]).doubleValue(), closeTo(0d, 10d)); try { client().prepareSearch("test").setQuery(matchAllQuery()) @@ -372,7 +372,7 @@ public void testDistanceSortingWithMissingGeoPoint() throws Exception { assertHitCount(searchResponse, 2); assertOrderedSearchHits(searchResponse, "1", "2"); - assertThat(((Number) searchResponse.getHits().getAt(0).sortValues()[0]).doubleValue(), closeTo(0.4621d, 0.01d)); + assertThat(((Number) searchResponse.getHits().getAt(0).sortValues()[0]).doubleValue(), closeTo(462.1d, 10d)); assertThat(((Number) searchResponse.getHits().getAt(1).sortValues()[0]).doubleValue(), equalTo(Double.MAX_VALUE)); // Order: Desc @@ -384,7 +384,7 @@ public void testDistanceSortingWithMissingGeoPoint() throws Exception { assertHitCount(searchResponse, 2); assertOrderedSearchHits(searchResponse, "2", "1"); assertThat(((Number) searchResponse.getHits().getAt(0).sortValues()[0]).doubleValue(), equalTo(Double.MAX_VALUE)); - assertThat(((Number) searchResponse.getHits().getAt(1).sortValues()[0]).doubleValue(), closeTo(5.286d, 0.01d)); + assertThat(((Number) searchResponse.getHits().getAt(1).sortValues()[0]).doubleValue(), closeTo(5286d, 10d)); } @Test @@ -409,11 +409,11 @@ public void distanceScriptTests() throws Exception { SearchResponse searchResponse1 = client().prepareSearch().addField("_source").addScriptField("distance", "doc['location'].arcDistance(" + target_lat + "," + target_long + ")").execute().actionGet(); Double resultDistance1 = searchResponse1.getHits().getHits()[0].getFields().get("distance").getValue(); - assertThat(resultDistance1, closeTo(GeoDistance.ARC.calculate(source_lat, source_long, target_lat, target_long, DistanceUnit.MILES), 0.0001d)); + assertThat(resultDistance1, closeTo(GeoDistance.ARC.calculate(source_lat, source_long, target_lat, target_long, DistanceUnit.DEFAULT), 0.0001d)); SearchResponse searchResponse2 = client().prepareSearch().addField("_source").addScriptField("distance", "doc['location'].distance(" + target_lat + "," + target_long + ")").execute().actionGet(); Double resultDistance2 = searchResponse2.getHits().getHits()[0].getFields().get("distance").getValue(); - assertThat(resultDistance2, closeTo(GeoDistance.PLANE.calculate(source_lat, source_long, target_lat, target_long, DistanceUnit.MILES), 0.0001d)); + assertThat(resultDistance2, closeTo(GeoDistance.PLANE.calculate(source_lat, source_long, target_lat, target_long, DistanceUnit.DEFAULT), 0.0001d)); SearchResponse searchResponse3 = client().prepareSearch().addField("_source").addScriptField("distance", "doc['location'].arcDistanceInKm(" + target_lat + "," + target_long + ")").execute().actionGet(); Double resultArcDistance3 = searchResponse3.getHits().getHits()[0].getFields().get("distance").getValue(); @@ -430,6 +430,15 @@ public void distanceScriptTests() throws Exception { SearchResponse searchResponse6 = client().prepareSearch().addField("_source").addScriptField("distance", "doc['location'].arcDistanceInKm(" + (target_lat + 360) + "," + (target_long) + ")").execute().actionGet(); Double resultArcDistance6 = searchResponse6.getHits().getHits()[0].getFields().get("distance").getValue(); assertThat(resultArcDistance6, closeTo(GeoDistance.ARC.calculate(source_lat, source_long, target_lat, target_long, DistanceUnit.KILOMETERS), 0.0001d)); + + SearchResponse searchResponse7 = client().prepareSearch().addField("_source").addScriptField("distance", "doc['location'].arcDistanceInMiles(" + target_lat + "," + target_long + ")").execute().actionGet(); + Double resultDistance7 = searchResponse7.getHits().getHits()[0].getFields().get("distance").getValue(); + assertThat(resultDistance7, closeTo(GeoDistance.ARC.calculate(source_lat, source_long, target_lat, target_long, DistanceUnit.MILES), 0.0001d)); + + SearchResponse searchResponse8 = client().prepareSearch().addField("_source").addScriptField("distance", "doc['location'].distanceInMiles(" + target_lat + "," + target_long + ")").execute().actionGet(); + Double resultDistance8 = searchResponse8.getHits().getHits()[0].getFields().get("distance").getValue(); + assertThat(resultDistance8, closeTo(GeoDistance.PLANE.calculate(source_lat, source_long, target_lat, target_long, DistanceUnit.MILES), 0.0001d)); + } @Test @@ -509,10 +518,10 @@ public void testDistanceSortingNestedFields() throws Exception { assertHitCount(searchResponse, 4); assertOrderedSearchHits(searchResponse, "1", "2", "3", "4"); - assertThat(((Number) searchResponse.getHits().getAt(0).sortValues()[0]).doubleValue(), closeTo(0d, 0.01d)); - assertThat(((Number) searchResponse.getHits().getAt(1).sortValues()[0]).doubleValue(), closeTo(0.4621d, 0.01d)); - assertThat(((Number) searchResponse.getHits().getAt(2).sortValues()[0]).doubleValue(), closeTo(1.055d, 0.01d)); - assertThat(((Number) searchResponse.getHits().getAt(3).sortValues()[0]).doubleValue(), closeTo(2.029d, 0.01d)); + assertThat(((Number) searchResponse.getHits().getAt(0).sortValues()[0]).doubleValue(), closeTo(0d, 10d)); + assertThat(((Number) searchResponse.getHits().getAt(1).sortValues()[0]).doubleValue(), closeTo(462.1d, 10d)); + assertThat(((Number) searchResponse.getHits().getAt(2).sortValues()[0]).doubleValue(), closeTo(1055.0d, 10d)); + assertThat(((Number) searchResponse.getHits().getAt(3).sortValues()[0]).doubleValue(), closeTo(2029.0d, 10d)); // Order: Asc, Mode: max searchResponse = client().prepareSearch("companies").setQuery(matchAllQuery()) @@ -521,10 +530,10 @@ public void testDistanceSortingNestedFields() throws Exception { assertHitCount(searchResponse, 4); assertOrderedSearchHits(searchResponse, "1", "3", "2", "4"); - assertThat(((Number) searchResponse.getHits().getAt(0).sortValues()[0]).doubleValue(), closeTo(0d, 0.01d)); - assertThat(((Number) searchResponse.getHits().getAt(1).sortValues()[0]).doubleValue(), closeTo(1.258d, 0.01d)); - assertThat(((Number) searchResponse.getHits().getAt(2).sortValues()[0]).doubleValue(), closeTo(5.286d, 0.01d)); - assertThat(((Number) searchResponse.getHits().getAt(3).sortValues()[0]).doubleValue(), closeTo(8.572d, 0.01d)); + assertThat(((Number) searchResponse.getHits().getAt(0).sortValues()[0]).doubleValue(), closeTo(0d, 10d)); + assertThat(((Number) searchResponse.getHits().getAt(1).sortValues()[0]).doubleValue(), closeTo(1258.0d, 10d)); + assertThat(((Number) searchResponse.getHits().getAt(2).sortValues()[0]).doubleValue(), closeTo(5286.0d, 10d)); + assertThat(((Number) searchResponse.getHits().getAt(3).sortValues()[0]).doubleValue(), closeTo(8572.0d, 10d)); // Order: Desc searchResponse = client().prepareSearch("companies").setQuery(matchAllQuery()) @@ -533,10 +542,10 @@ public void testDistanceSortingNestedFields() throws Exception { assertHitCount(searchResponse, 4); assertOrderedSearchHits(searchResponse, "4", "2", "3", "1"); - assertThat(((Number) searchResponse.getHits().getAt(0).sortValues()[0]).doubleValue(), closeTo(8.572d, 0.01d)); - assertThat(((Number) searchResponse.getHits().getAt(1).sortValues()[0]).doubleValue(), closeTo(5.286d, 0.01d)); - assertThat(((Number) searchResponse.getHits().getAt(2).sortValues()[0]).doubleValue(), closeTo(1.258d, 0.01d)); - assertThat(((Number) searchResponse.getHits().getAt(3).sortValues()[0]).doubleValue(), closeTo(0d, 0.01d)); + assertThat(((Number) searchResponse.getHits().getAt(0).sortValues()[0]).doubleValue(), closeTo(8572.0d, 10d)); + assertThat(((Number) searchResponse.getHits().getAt(1).sortValues()[0]).doubleValue(), closeTo(5286.0d, 10d)); + assertThat(((Number) searchResponse.getHits().getAt(2).sortValues()[0]).doubleValue(), closeTo(1258.0d, 10d)); + assertThat(((Number) searchResponse.getHits().getAt(3).sortValues()[0]).doubleValue(), closeTo(0d, 10d)); // Order: Desc, Mode: min searchResponse = client().prepareSearch("companies").setQuery(matchAllQuery()) @@ -545,10 +554,10 @@ public void testDistanceSortingNestedFields() throws Exception { assertHitCount(searchResponse, 4); assertOrderedSearchHits(searchResponse, "4", "3", "2", "1"); - assertThat(((Number) searchResponse.getHits().getAt(0).sortValues()[0]).doubleValue(), closeTo(2.029d, 0.01d)); - assertThat(((Number) searchResponse.getHits().getAt(1).sortValues()[0]).doubleValue(), closeTo(1.055d, 0.01d)); - assertThat(((Number) searchResponse.getHits().getAt(2).sortValues()[0]).doubleValue(), closeTo(0.4621d, 0.01d)); - assertThat(((Number) searchResponse.getHits().getAt(3).sortValues()[0]).doubleValue(), closeTo(0d, 0.01d)); + assertThat(((Number) searchResponse.getHits().getAt(0).sortValues()[0]).doubleValue(), closeTo(2029.0d, 10d)); + assertThat(((Number) searchResponse.getHits().getAt(1).sortValues()[0]).doubleValue(), closeTo(1055.0d, 10d)); + assertThat(((Number) searchResponse.getHits().getAt(2).sortValues()[0]).doubleValue(), closeTo(462.1d, 10d)); + assertThat(((Number) searchResponse.getHits().getAt(3).sortValues()[0]).doubleValue(), closeTo(0d, 10d)); searchResponse = client().prepareSearch("companies").setQuery(matchAllQuery()) .addSort(SortBuilders.geoDistanceSort("branches.location").point(40.7143528, -74.0059731).sortMode("avg").order(SortOrder.ASC)) @@ -556,10 +565,10 @@ public void testDistanceSortingNestedFields() throws Exception { assertHitCount(searchResponse, 4); assertOrderedSearchHits(searchResponse, "1", "3", "2", "4"); - assertThat(((Number) searchResponse.getHits().getAt(0).sortValues()[0]).doubleValue(), closeTo(0d, 0.01d)); - assertThat(((Number) searchResponse.getHits().getAt(1).sortValues()[0]).doubleValue(), closeTo(1.157d, 0.01d)); - assertThat(((Number) searchResponse.getHits().getAt(2).sortValues()[0]).doubleValue(), closeTo(2.874d, 0.01d)); - assertThat(((Number) searchResponse.getHits().getAt(3).sortValues()[0]).doubleValue(), closeTo(5.301d, 0.01d)); + assertThat(((Number) searchResponse.getHits().getAt(0).sortValues()[0]).doubleValue(), closeTo(0d, 10d)); + assertThat(((Number) searchResponse.getHits().getAt(1).sortValues()[0]).doubleValue(), closeTo(1157.0d, 10d)); + assertThat(((Number) searchResponse.getHits().getAt(2).sortValues()[0]).doubleValue(), closeTo(2874.0d, 10d)); + assertThat(((Number) searchResponse.getHits().getAt(3).sortValues()[0]).doubleValue(), closeTo(5301.0d, 10d)); searchResponse = client().prepareSearch("companies").setQuery(matchAllQuery()) .addSort( @@ -570,10 +579,10 @@ public void testDistanceSortingNestedFields() throws Exception { assertHitCount(searchResponse, 4); assertOrderedSearchHits(searchResponse, "4", "2", "3", "1"); - assertThat(((Number) searchResponse.getHits().getAt(0).sortValues()[0]).doubleValue(), closeTo(5.301d, 0.01d)); - assertThat(((Number) searchResponse.getHits().getAt(1).sortValues()[0]).doubleValue(), closeTo(2.874d, 0.01d)); - assertThat(((Number) searchResponse.getHits().getAt(2).sortValues()[0]).doubleValue(), closeTo(1.157d, 0.01d)); - assertThat(((Number) searchResponse.getHits().getAt(3).sortValues()[0]).doubleValue(), closeTo(0d, 0.01d)); + assertThat(((Number) searchResponse.getHits().getAt(0).sortValues()[0]).doubleValue(), closeTo(5301.0d, 10d)); + assertThat(((Number) searchResponse.getHits().getAt(1).sortValues()[0]).doubleValue(), closeTo(2874.0d, 10d)); + assertThat(((Number) searchResponse.getHits().getAt(2).sortValues()[0]).doubleValue(), closeTo(1157.0d, 10d)); + assertThat(((Number) searchResponse.getHits().getAt(3).sortValues()[0]).doubleValue(), closeTo(0d, 10d)); searchResponse = client().prepareSearch("companies").setQuery(matchAllQuery()) .addSort( @@ -584,7 +593,7 @@ public void testDistanceSortingNestedFields() throws Exception { assertHitCount(searchResponse, 4); assertFirstHit(searchResponse, hasId("4")); assertSearchHits(searchResponse, "1", "2", "3", "4"); - assertThat(((Number) searchResponse.getHits().getAt(0).sortValues()[0]).doubleValue(), closeTo(8.572d, 0.01d)); + assertThat(((Number) searchResponse.getHits().getAt(0).sortValues()[0]).doubleValue(), closeTo(8572.0d, 10d)); assertThat(((Number) searchResponse.getHits().getAt(1).sortValues()[0]).doubleValue(), equalTo(Double.MAX_VALUE)); assertThat(((Number) searchResponse.getHits().getAt(2).sortValues()[0]).doubleValue(), equalTo(Double.MAX_VALUE)); assertThat(((Number) searchResponse.getHits().getAt(3).sortValues()[0]).doubleValue(), equalTo(Double.MAX_VALUE)); diff --git a/src/test/java/org/elasticsearch/validate/SimpleValidateQueryTests.java b/src/test/java/org/elasticsearch/validate/SimpleValidateQueryTests.java index 573596daf764a..c6214fa52b2d6 100644 --- a/src/test/java/org/elasticsearch/validate/SimpleValidateQueryTests.java +++ b/src/test/java/org/elasticsearch/validate/SimpleValidateQueryTests.java @@ -39,7 +39,7 @@ import java.io.IOException; import static org.elasticsearch.index.query.QueryBuilders.queryString; -import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.*; +import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertNoFailures; import static org.hamcrest.Matchers.*; /** @@ -136,7 +136,8 @@ public void explainValidateQuery() throws Exception { .addPoint(40, -70) .addPoint(30, -80) .addPoint(20, -90) - ), equalTo("ConstantScore(GeoPolygonFilter(pin.location, [[40.0, -70.0], [30.0, -80.0], [20.0, -90.0]]))")); + .addPoint(40, -70) // closing polygon + ), equalTo("ConstantScore(GeoPolygonFilter(pin.location, [[40.0, -70.0], [30.0, -80.0], [20.0, -90.0], [40.0, -70.0]]))")); assertExplanation(QueryBuilders.constantScoreQuery(FilterBuilders.geoBoundingBoxFilter("pin.location") .topLeft(40, -80) @@ -144,17 +145,21 @@ public void explainValidateQuery() throws Exception { ), equalTo("ConstantScore(GeoBoundingBoxFilter(pin.location, [40.0, -80.0], [20.0, -70.0]))")); assertExplanation(QueryBuilders.constantScoreQuery(FilterBuilders.geoDistanceFilter("pin.location") - .lat(10).lon(20).distance(15, DistanceUnit.MILES).geoDistance(GeoDistance.PLANE) + .lat(10).lon(20).distance(15, DistanceUnit.DEFAULT).geoDistance(GeoDistance.PLANE) ), equalTo("ConstantScore(GeoDistanceFilter(pin.location, PLANE, 15.0, 10.0, 20.0))")); assertExplanation(QueryBuilders.constantScoreQuery(FilterBuilders.geoDistanceFilter("pin.location") - .lat(10).lon(20).distance(15, DistanceUnit.MILES).geoDistance(GeoDistance.PLANE) + .lat(10).lon(20).distance(15, DistanceUnit.DEFAULT).geoDistance(GeoDistance.PLANE) ), equalTo("ConstantScore(GeoDistanceFilter(pin.location, PLANE, 15.0, 10.0, 20.0))")); assertExplanation(QueryBuilders.constantScoreQuery(FilterBuilders.geoDistanceRangeFilter("pin.location") - .lat(10).lon(20).from("15miles").to("25miles").geoDistance(GeoDistance.PLANE) + .lat(10).lon(20).from("15m").to("25m").geoDistance(GeoDistance.PLANE) ), equalTo("ConstantScore(GeoDistanceRangeFilter(pin.location, PLANE, [15.0 - 25.0], 10.0, 20.0))")); + assertExplanation(QueryBuilders.constantScoreQuery(FilterBuilders.geoDistanceRangeFilter("pin.location") + .lat(10).lon(20).from("15miles").to("25miles").geoDistance(GeoDistance.PLANE) + ), equalTo("ConstantScore(GeoDistanceRangeFilter(pin.location, PLANE, [" + DistanceUnit.DEFAULT.convert(15.0, DistanceUnit.MILES) + " - " + DistanceUnit.DEFAULT.convert(25.0, DistanceUnit.MILES) + "], 10.0, 20.0))")); + assertExplanation(QueryBuilders.filteredQuery( QueryBuilders.termQuery("foo", "1"), FilterBuilders.andFilter(