diff --git a/src/main/java/org/elasticsearch/search/sort/GeoDistanceSortBuilder.java b/src/main/java/org/elasticsearch/search/sort/GeoDistanceSortBuilder.java index f8bb20805b6..f42cabf84bf 100644 --- a/src/main/java/org/elasticsearch/search/sort/GeoDistanceSortBuilder.java +++ b/src/main/java/org/elasticsearch/search/sort/GeoDistanceSortBuilder.java @@ -152,20 +152,16 @@ public class GeoDistanceSortBuilder extends SortBuilder { if (geohashes.size() == 0 && points.size() == 0) { throw new ElasticsearchParseException("No points provided for _geo_distance sort."); } - if (geohashes.size() == 1 && points.size() == 0) { - builder.field(fieldName, geohashes.get(0)); - } else if (geohashes.size() == 1 && points.size() == 0) { - builder.field(fieldName, points.get(0)); - } else { - builder.startArray(fieldName); - for (GeoPoint point : points) { - builder.value(point); - } - for (String geohash : geohashes) { - builder.value(geohash); - } - builder.endArray(); + + builder.startArray(fieldName); + for (GeoPoint point : points) { + builder.value(point); } + for (String geohash : geohashes) { + builder.value(geohash); + } + builder.endArray(); + if (unit != null) { builder.field("unit", unit); } diff --git a/src/test/java/org/elasticsearch/search/sort/SimpleSortTests.java b/src/test/java/org/elasticsearch/search/sort/SimpleSortTests.java index 5f7ba306b1e..c28d7285a2e 100644 --- a/src/test/java/org/elasticsearch/search/sort/SimpleSortTests.java +++ b/src/test/java/org/elasticsearch/search/sort/SimpleSortTests.java @@ -1907,6 +1907,85 @@ public class SimpleSortTests extends ElasticsearchIntegrationTest { assertThat((Double) searchResponse.getHits().getAt(1).getSortValues()[0], closeTo(GeoDistance.PLANE.calculate(4.5, 1, 2, 1, DistanceUnit.KILOMETERS), 1.e-5)); } + public void testSinglePointGeoDistanceSort() throws ExecutionException, InterruptedException, IOException { + assertAcked(prepareCreate("index").addMapping("type", "location", "type=geo_point")); + indexRandom(true, + client().prepareIndex("index", "type", "d1").setSource(jsonBuilder().startObject().startObject("location").field("lat", 1).field("lon", 1).endObject().endObject()), + client().prepareIndex("index", "type", "d2").setSource(jsonBuilder().startObject().startObject("location").field("lat", 1).field("lon", 2).endObject().endObject())); + ensureYellow(); + + String hashPoint = "s037ms06g7h0"; + + GeoDistanceSortBuilder geoDistanceSortBuilder = new GeoDistanceSortBuilder("location"); + geoDistanceSortBuilder.geohashes(hashPoint); + + SearchResponse searchResponse = client().prepareSearch() + .setQuery(matchAllQuery()) + .addSort(geoDistanceSortBuilder.sortMode("min").order(SortOrder.ASC).geoDistance(GeoDistance.PLANE).unit(DistanceUnit.KILOMETERS)) + .execute().actionGet(); + checkCorrectSortOrderForGeoSort(searchResponse); + + geoDistanceSortBuilder = new GeoDistanceSortBuilder("location"); + geoDistanceSortBuilder.points(new GeoPoint(2, 2)); + + searchResponse = client().prepareSearch() + .setQuery(matchAllQuery()) + .addSort(geoDistanceSortBuilder.sortMode("min").order(SortOrder.ASC).geoDistance(GeoDistance.PLANE).unit(DistanceUnit.KILOMETERS)) + .execute().actionGet(); + checkCorrectSortOrderForGeoSort(searchResponse); + + geoDistanceSortBuilder = new GeoDistanceSortBuilder("location"); + geoDistanceSortBuilder.point(2, 2); + + searchResponse = client().prepareSearch() + .setQuery(matchAllQuery()) + .addSort(geoDistanceSortBuilder.sortMode("min").order(SortOrder.ASC).geoDistance(GeoDistance.PLANE).unit(DistanceUnit.KILOMETERS)) + .execute().actionGet(); + checkCorrectSortOrderForGeoSort(searchResponse); + + String geoSortRequest = jsonBuilder().startObject().startArray("sort").startObject() + .startObject("_geo_distance") + .startArray("location").value(2f).value(2f).endArray() + .field("unit", "km") + .field("distance_type", "plane") + .endObject() + .endObject().endArray().string(); + searchResponse = client().prepareSearch().setSource(geoSortRequest) + .execute().actionGet(); + checkCorrectSortOrderForGeoSort(searchResponse); + + geoSortRequest = jsonBuilder().startObject().startArray("sort").startObject() + .startObject("_geo_distance") + .field("location", "s037ms06g7h0") + .field("unit", "km") + .field("distance_type", "plane") + .endObject() + .endObject().endArray().string(); + searchResponse = client().prepareSearch().setSource(geoSortRequest) + .execute().actionGet(); + checkCorrectSortOrderForGeoSort(searchResponse); + + geoSortRequest = jsonBuilder().startObject().startArray("sort").startObject() + .startObject("_geo_distance") + .startObject("location") + .field("lat", 2) + .field("lon", 2) + .endObject() + .field("unit", "km") + .field("distance_type", "plane") + .endObject() + .endObject().endArray().string(); + searchResponse = client().prepareSearch().setSource(geoSortRequest) + .execute().actionGet(); + checkCorrectSortOrderForGeoSort(searchResponse); + } + + private void checkCorrectSortOrderForGeoSort(SearchResponse searchResponse) { + assertOrderedSearchHits(searchResponse, "d2", "d1"); + assertThat((Double) searchResponse.getHits().getAt(0).getSortValues()[0], closeTo(GeoDistance.PLANE.calculate(2, 2, 1, 2, DistanceUnit.KILOMETERS), 1.e-5)); + assertThat((Double) searchResponse.getHits().getAt(1).getSortValues()[0], closeTo(GeoDistance.PLANE.calculate(2, 2, 1, 1, DistanceUnit.KILOMETERS), 1.e-5)); + } + protected void createQPoints(List qHashes, List qPoints) { GeoPoint[] qp = {new GeoPoint(2, 1), new GeoPoint(2, 2), new GeoPoint(2, 3), new GeoPoint(2, 4)}; qPoints.addAll(Arrays.asList(qp));