diff --git a/docs/reference/query-dsl/geo-bounding-box-query.asciidoc b/docs/reference/query-dsl/geo-bounding-box-query.asciidoc
index ca355413b2e5c..afa1175055719 100644
--- a/docs/reference/query-dsl/geo-bounding-box-query.asciidoc
+++ b/docs/reference/query-dsl/geo-bounding-box-query.asciidoc
@@ -4,8 +4,13 @@
Geo-bounding box
++++
-A query allowing to filter hits based on a point location using a
-bounding box. Assuming the following indexed document:
+Matches <> and <> values that
+intersect a bounding box.
+
+[discrete]
+[[geo-bounding-box-query-ex]]
+==== Example
+Assume the following the following documents are indexed:
[source,console]
--------------------------------------------------
@@ -33,11 +38,36 @@ PUT /my_locations/_doc/1
}
}
}
+
+PUT /my_geoshapes
+{
+ "mappings": {
+ "properties": {
+ "pin": {
+ "properties": {
+ "location": {
+ "type": "geo_shape"
+ }
+ }
+ }
+ }
+ }
+}
+
+PUT /my_geoshapes/_doc/1
+{
+ "pin": {
+ "location": {
+ "type" : "polygon",
+ "coordinates" : [[[13.0 ,51.5], [15.0, 51.5], [15.0, 54.0], [13.0, 54.0], [13.0 ,51.5]]]
+ }
+ }
+}
--------------------------------------------------
// TESTSETUP
-Then the following simple query can be executed with a
-`geo_bounding_box` filter:
+Use a `geo_bounding_box` filter to match `geo_point` values that intersect a bounding
+box. To define the box, provide geopoint values for two opposite corners.
[source,console]
--------------------------------------------------
@@ -67,6 +97,66 @@ GET my_locations/_search
}
--------------------------------------------------
+Use the same filter to match `geo_shape` values that intersect the bounding box:
+
+[source,console]
+--------------------------------------------------
+GET my_geoshapes/_search
+{
+ "query": {
+ "bool": {
+ "must": {
+ "match_all": {}
+ },
+ "filter": {
+ "geo_bounding_box": {
+ "pin.location": {
+ "top_left": {
+ "lat": 40.73,
+ "lon": -74.1
+ },
+ "bottom_right": {
+ "lat": 40.01,
+ "lon": -71.12
+ }
+ }
+ }
+ }
+ }
+ }
+}
+--------------------------------------------------
+
+To match both `geo_point` and `geo_shape` values, search both indices:
+
+[source,console]
+--------------------------------------------------
+GET my_locations,my_geoshapes/_search
+{
+ "query": {
+ "bool": {
+ "must": {
+ "match_all": {}
+ },
+ "filter": {
+ "geo_bounding_box": {
+ "pin.location": {
+ "top_left": {
+ "lat": 40.73,
+ "lon": -74.1
+ },
+ "bottom_right": {
+ "lat": 40.01,
+ "lon": -71.12
+ }
+ }
+ }
+ }
+ }
+ }
+}
+--------------------------------------------------
+
[discrete]
==== Query Options
@@ -291,13 +381,6 @@ GET my_locations/_search
}
--------------------------------------------------
-
-[discrete]
-==== geo_point Type
-
-The filter *requires* the `geo_point` type to be set on the relevant
-field.
-
[discrete]
==== Multi Location Per Document
@@ -366,3 +449,8 @@ the upper bounds (top and right edges) might be selected by the query even if
they are located slightly outside the edge. The rounding error should be less
than 4.20e-8 degrees on the latitude and less than 8.39e-8 degrees on the
longitude, which translates to less than 1cm error even at the equator.
+
+Geoshapes also have limited precision due to rounding. Geoshape edges along the
+bounding box's bottom and left edges may not match a `geo_bounding_box` query.
+Geoshape edges slightly outside the box's top and right edges may still match
+the query.
diff --git a/docs/reference/query-dsl/geo-distance-query.asciidoc b/docs/reference/query-dsl/geo-distance-query.asciidoc
index cfb2779659e2b..be76c24402c7a 100644
--- a/docs/reference/query-dsl/geo-distance-query.asciidoc
+++ b/docs/reference/query-dsl/geo-distance-query.asciidoc
@@ -4,9 +4,14 @@
Geo-distance
++++
-Filters documents that include only hits that exists within a specific
-distance from a geo point. Assuming the following mapping and indexed
-document:
+Matches <> and <> values within
+a given distance of a geopoint.
+
+[discrete]
+[[geo-distance-query-ex]]
+==== Example
+
+Assume the following the following documents are indexed:
[source,console]
--------------------------------------------------
@@ -34,12 +39,37 @@ PUT /my_locations/_doc/1
}
}
}
+
+PUT /my_geoshapes
+{
+ "mappings": {
+ "properties": {
+ "pin": {
+ "properties": {
+ "location": {
+ "type": "geo_shape"
+ }
+ }
+ }
+ }
+ }
+}
+
+PUT /my_geoshapes/_doc/1
+{
+ "pin": {
+ "location": {
+ "type" : "polygon",
+ "coordinates" : [[[13.0 ,51.5], [15.0, 51.5], [15.0, 54.0], [13.0, 54.0], [13.0 ,51.5]]]
+ }
+ }
+}
--------------------------------------------------
// TESTSETUP
-Then the following simple query can be executed with a `geo_distance`
-filter:
+Use a `geo_distance` filter to match `geo_point` values within a specified
+distance of another geopoint:
[source,console]
--------------------------------------------------
@@ -64,6 +94,57 @@ GET /my_locations/_search
}
--------------------------------------------------
+Use the same filter to match `geo_shape` values within the given distance:
+
+[source,console]
+--------------------------------------------------
+GET my_geoshapes/_search
+{
+ "query": {
+ "bool": {
+ "must": {
+ "match_all": {}
+ },
+ "filter": {
+ "geo_distance": {
+ "distance": "200km",
+ "pin.location": {
+ "lat": 40,
+ "lon": -70
+ }
+ }
+ }
+ }
+ }
+}
+--------------------------------------------------
+
+To match both `geo_point` and `geo_shape` values, search both indices:
+
+[source,console]
+--------------------------------------------------
+GET my_locations,my_geoshapes/_search
+{
+ "query": {
+ "bool": {
+ "must": {
+ "match_all": {}
+ },
+ "filter": {
+ "geo_distance": {
+ "distance": "200km",
+ "pin.location": {
+ "lat": 40,
+ "lon": -70
+ }
+ }
+ }
+ }
+ }
+}
+--------------------------------------------------
+
+
[discrete]
==== Accepted Formats
@@ -198,12 +279,6 @@ The following are options allowed on the filter:
longitude, set to `COERCE` to additionally try and infer correct
coordinates (default is `STRICT`).
-[discrete]
-==== geo_point Type
-
-The filter *requires* the `geo_point` type to be set on the relevant
-field.
-
[discrete]
==== Multi Location Per Document
diff --git a/server/src/internalClusterTest/java/org/elasticsearch/search/geo/AbstractGeoBoundingBoxQueryIT.java b/server/src/internalClusterTest/java/org/elasticsearch/search/geo/AbstractGeoBoundingBoxQueryIT.java
new file mode 100644
index 0000000000000..5cfe2bfe6bc95
--- /dev/null
+++ b/server/src/internalClusterTest/java/org/elasticsearch/search/geo/AbstractGeoBoundingBoxQueryIT.java
@@ -0,0 +1,276 @@
+/*
+ * Licensed to Elasticsearch under one or more contributor
+ * license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright
+ * ownership. Elasticsearch licenses this file to you under
+ * the Apache License, Version 2.0 (the "License"); you may
+ * not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.elasticsearch.search.geo;
+
+import org.elasticsearch.Version;
+import org.elasticsearch.action.search.SearchResponse;
+import org.elasticsearch.cluster.metadata.IndexMetadata;
+import org.elasticsearch.common.settings.Settings;
+import org.elasticsearch.common.unit.DistanceUnit;
+import org.elasticsearch.common.xcontent.XContentBuilder;
+import org.elasticsearch.index.query.GeoValidationMethod;
+import org.elasticsearch.search.SearchHit;
+import org.elasticsearch.test.ESIntegTestCase;
+import org.elasticsearch.test.VersionUtils;
+
+import java.io.IOException;
+
+import static org.elasticsearch.action.support.WriteRequest.RefreshPolicy.IMMEDIATE;
+import static org.elasticsearch.common.xcontent.XContentFactory.jsonBuilder;
+import static org.elasticsearch.index.query.QueryBuilders.boolQuery;
+import static org.elasticsearch.index.query.QueryBuilders.geoBoundingBoxQuery;
+import static org.elasticsearch.index.query.QueryBuilders.geoDistanceQuery;
+import static org.elasticsearch.index.query.QueryBuilders.termQuery;
+import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertAcked;
+import static org.hamcrest.Matchers.anyOf;
+import static org.hamcrest.Matchers.equalTo;
+
+abstract class AbstractGeoBoundingBoxQueryIT extends ESIntegTestCase {
+
+ @Override
+ protected boolean forbidPrivateIndexSettings() {
+ return false;
+ }
+
+ public abstract XContentBuilder getMapping() throws IOException;
+
+ public void testSimpleBoundingBoxTest() throws Exception {
+ Version version = VersionUtils.randomIndexCompatibleVersion(random());
+ Settings settings = Settings.builder().put(IndexMetadata.SETTING_VERSION_CREATED, version).build();
+ XContentBuilder xContentBuilder = getMapping();
+ assertAcked(prepareCreate("test").setSettings(settings).addMapping("type1", xContentBuilder));
+ ensureGreen();
+
+ client().prepareIndex("test", "type1", "1").setSource(jsonBuilder().startObject()
+ .field("name", "New York")
+ .field("location", "POINT(-74.0059731 40.7143528)")
+ .endObject()).get();
+
+ // to NY: 5.286 km
+ client().prepareIndex("test", "type1", "2").setSource(jsonBuilder().startObject()
+ .field("name", "Times Square")
+ .field("location", "POINT(-73.9844722 40.759011)")
+ .endObject()).get();
+
+ // to NY: 0.4621 km
+ client().prepareIndex("test", "type1", "3").setSource(jsonBuilder().startObject()
+ .field("name", "Tribeca")
+ .field("location", "POINT(-74.007819 40.718266)")
+ .endObject()).get();
+
+ // to NY: 1.055 km
+ client().prepareIndex("test", "type1", "4").setSource(jsonBuilder().startObject()
+ .field("name", "Wall Street")
+ .field("location", "POINT(-74.0088305 40.7051157)")
+ .endObject()).get();
+
+ // to NY: 1.258 km
+ client().prepareIndex("test", "type1", "5").setSource(jsonBuilder().startObject()
+ .field("name", "Soho")
+ .field("location", "POINT(-74 40.7247222)")
+ .endObject()).get();
+
+ // to NY: 2.029 km
+ client().prepareIndex("test", "type1", "6").setSource(jsonBuilder().startObject()
+ .field("name", "Greenwich Village")
+ .field("location", "POINT(-73.9962255 40.731033)")
+ .endObject()).get();
+
+ // to NY: 8.572 km
+ client().prepareIndex("test", "type1", "7").setSource(jsonBuilder().startObject()
+ .field("name", "Brooklyn")
+ .field("location", "POINT(-73.95 40.65)")
+ .endObject()).get();
+
+ client().admin().indices().prepareRefresh().get();
+
+ SearchResponse searchResponse = client().prepareSearch() // from NY
+ .setQuery(geoBoundingBoxQuery("location").setCorners(40.73, -74.1, 40.717, -73.99))
+ .get();
+ assertThat(searchResponse.getHits().getTotalHits().value, equalTo(2L));
+ assertThat(searchResponse.getHits().getHits().length, equalTo(2));
+ for (SearchHit hit : searchResponse.getHits()) {
+ assertThat(hit.getId(), anyOf(equalTo("1"), equalTo("3"), equalTo("5")));
+ }
+
+ searchResponse = client().prepareSearch() // from NY
+ .setQuery(geoBoundingBoxQuery("location").setCorners(40.73, -74.1, 40.717, -73.99).type("indexed"))
+ .get();
+ assertThat(searchResponse.getHits().getTotalHits().value, equalTo(2L));
+ assertThat(searchResponse.getHits().getHits().length, equalTo(2));
+ for (SearchHit hit : searchResponse.getHits()) {
+ assertThat(hit.getId(), anyOf(equalTo("1"), equalTo("3"), equalTo("5")));
+ }
+ // Distance query
+ searchResponse = client().prepareSearch() // from NY
+ .setQuery(geoDistanceQuery("location").point(40.5, -73.9).distance(25, DistanceUnit.KILOMETERS))
+ .get();
+ assertThat(searchResponse.getHits().getTotalHits().value, equalTo(2L));
+ assertThat(searchResponse.getHits().getHits().length, equalTo(2));
+ for (SearchHit hit : searchResponse.getHits()) {
+ assertThat(hit.getId(), anyOf(equalTo("7"), equalTo("4")));
+ }
+ }
+
+ public void testLimit2BoundingBox() throws Exception {
+ Version version = VersionUtils.randomIndexCompatibleVersion(random());
+ Settings settings = Settings.builder().put(IndexMetadata.SETTING_VERSION_CREATED, version).build();
+ XContentBuilder xContentBuilder = getMapping();
+ assertAcked(prepareCreate("test").setSettings(settings).addMapping("type1", xContentBuilder));
+ ensureGreen();
+
+ client().prepareIndex("test", "type1", "1").setSource(jsonBuilder().startObject()
+ .field("userid", 880)
+ .field("title", "Place in Stockholm")
+ .field("location", "POINT(59.328355000000002 18.036842)")
+ .endObject())
+ .setRefreshPolicy(IMMEDIATE)
+ .get();
+
+ client().prepareIndex("test", "type1", "2").setSource(jsonBuilder().startObject()
+ .field("userid", 534)
+ .field("title", "Place in Montreal")
+ .field("location", "POINT(-73.570986000000005 45.509526999999999)")
+ .endObject())
+ .setRefreshPolicy(IMMEDIATE)
+ .get();
+
+ SearchResponse searchResponse = client().prepareSearch()
+ .setQuery(
+ boolQuery().must(termQuery("userid", 880)).filter(
+ geoBoundingBoxQuery("location").setCorners(74.579421999999994, 143.5, -66.668903999999998, 113.96875))
+ ).get();
+ assertThat(searchResponse.getHits().getTotalHits().value, equalTo(1L));
+ searchResponse = client().prepareSearch()
+ .setQuery(
+ boolQuery().must(termQuery("userid", 880)).filter(
+ geoBoundingBoxQuery("location").setCorners(74.579421999999994, 143.5, -66.668903999999998, 113.96875)
+ .type("indexed"))
+ ).get();
+ assertThat(searchResponse.getHits().getTotalHits().value, equalTo(1L));
+
+ searchResponse = client().prepareSearch()
+ .setQuery(
+ boolQuery().must(termQuery("userid", 534)).filter(
+ geoBoundingBoxQuery("location").setCorners(74.579421999999994, 143.5, -66.668903999999998, 113.96875))
+ ).get();
+ assertThat(searchResponse.getHits().getTotalHits().value, equalTo(1L));
+ searchResponse = client().prepareSearch()
+ .setQuery(
+ boolQuery().must(termQuery("userid", 534)).filter(
+ geoBoundingBoxQuery("location").setCorners(74.579421999999994, 143.5, -66.668903999999998, 113.96875)
+ .type("indexed"))
+ ).get();
+ assertThat(searchResponse.getHits().getTotalHits().value, equalTo(1L));
+
+ // Distance query
+ searchResponse = client().prepareSearch()
+ .setQuery(
+ boolQuery().must(termQuery("userid", 880)).filter(
+ geoDistanceQuery("location").point(20, 60.0).distance(500, DistanceUnit.MILES))
+ ).get();
+ assertThat(searchResponse.getHits().getTotalHits().value, equalTo(1L));
+
+ searchResponse = client().prepareSearch()
+ .setQuery(
+ boolQuery().must(termQuery("userid", 534)).filter(
+ geoDistanceQuery("location").point(45.0, -73.0).distance(500, DistanceUnit.MILES))
+ ).get();
+ assertThat(searchResponse.getHits().getTotalHits().value, equalTo(1L));
+ }
+
+ public void testCompleteLonRange() throws Exception {
+ Version version = VersionUtils.randomIndexCompatibleVersion(random());
+ Settings settings = Settings.builder().put(IndexMetadata.SETTING_VERSION_CREATED, version).build();
+ XContentBuilder xContentBuilder = getMapping();
+ assertAcked(prepareCreate("test").setSettings(settings).addMapping("type1", xContentBuilder));
+ ensureGreen();
+
+ client().prepareIndex("test", "type1", "1").setSource(jsonBuilder().startObject()
+ .field("userid", 880)
+ .field("title", "Place in Stockholm")
+ .field("location", "POINT(18.036842 59.328355000000002)")
+ .endObject())
+ .setRefreshPolicy(IMMEDIATE)
+ .get();
+
+ client().prepareIndex("test", "type1", "2").setSource(jsonBuilder().startObject()
+ .field("userid", 534)
+ .field("title", "Place in Montreal")
+ .field("location", "POINT(-73.570986000000005 45.509526999999999)")
+ .endObject())
+ .setRefreshPolicy(IMMEDIATE)
+ .get();
+
+ SearchResponse searchResponse = client().prepareSearch()
+ .setQuery(
+ geoBoundingBoxQuery("location").setValidationMethod(GeoValidationMethod.COERCE).setCorners(50, -180, -50, 180)
+ ).get();
+ assertThat(searchResponse.getHits().getTotalHits().value, equalTo(1L));
+ searchResponse = client().prepareSearch()
+ .setQuery(
+ geoBoundingBoxQuery("location").setValidationMethod(GeoValidationMethod.COERCE).setCorners(50, -180, -50, 180)
+ .type("indexed")
+ ).get();
+ assertThat(searchResponse.getHits().getTotalHits().value, equalTo(1L));
+ searchResponse = client().prepareSearch()
+ .setQuery(
+ geoBoundingBoxQuery("location").setValidationMethod(GeoValidationMethod.COERCE).setCorners(90, -180, -90, 180)
+ ).get();
+ assertThat(searchResponse.getHits().getTotalHits().value, equalTo(2L));
+ searchResponse = client().prepareSearch()
+ .setQuery(
+ geoBoundingBoxQuery("location").setValidationMethod(GeoValidationMethod.COERCE).setCorners(90, -180, -90, 180)
+ .type("indexed")
+ ).get();
+ assertThat(searchResponse.getHits().getTotalHits().value, equalTo(2L));
+
+ searchResponse = client().prepareSearch()
+ .setQuery(
+ geoBoundingBoxQuery("location").setValidationMethod(GeoValidationMethod.COERCE).setCorners(50, 0, -50, 360)
+ ).get();
+ assertThat(searchResponse.getHits().getTotalHits().value, equalTo(1L));
+ searchResponse = client().prepareSearch()
+ .setQuery(
+ geoBoundingBoxQuery("location").setValidationMethod(GeoValidationMethod.COERCE).setCorners(50, 0, -50, 360)
+ .type("indexed")
+ ).get();
+ assertThat(searchResponse.getHits().getTotalHits().value, equalTo(1L));
+ searchResponse = client().prepareSearch()
+ .setQuery(
+ geoBoundingBoxQuery("location").setValidationMethod(GeoValidationMethod.COERCE).setCorners(90, 0, -90, 360)
+ ).get();
+ assertThat(searchResponse.getHits().getTotalHits().value, equalTo(2L));
+ searchResponse = client().prepareSearch()
+ .setQuery(
+ geoBoundingBoxQuery("location").setValidationMethod(GeoValidationMethod.COERCE).setCorners(90, 0, -90, 360)
+ .type("indexed")
+ ).get();
+ assertThat(searchResponse.getHits().getTotalHits().value, equalTo(2L));
+
+ // Distance query
+ searchResponse = client().prepareSearch()
+ .setQuery(
+ geoDistanceQuery("location").point(60.0, -20.0).distance(1800, DistanceUnit.MILES)
+ ).get();
+ assertThat(searchResponse.getHits().getTotalHits().value, equalTo(1L));
+ }
+}
+
diff --git a/server/src/internalClusterTest/java/org/elasticsearch/search/geo/GeoBoundingBoxQueryGeoPointIT.java b/server/src/internalClusterTest/java/org/elasticsearch/search/geo/GeoBoundingBoxQueryGeoPointIT.java
new file mode 100644
index 0000000000000..3dd90b6501551
--- /dev/null
+++ b/server/src/internalClusterTest/java/org/elasticsearch/search/geo/GeoBoundingBoxQueryGeoPointIT.java
@@ -0,0 +1,37 @@
+/*
+ * Licensed to Elasticsearch under one or more contributor
+ * license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright
+ * ownership. Elasticsearch licenses this file to you under
+ * the Apache License, Version 2.0 (the "License"); you may
+ * not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.elasticsearch.search.geo;
+
+import org.elasticsearch.common.xcontent.XContentBuilder;
+import org.elasticsearch.common.xcontent.XContentFactory;
+
+import java.io.IOException;
+
+public class GeoBoundingBoxQueryGeoPointIT extends AbstractGeoBoundingBoxQueryIT {
+
+ @Override
+ public XContentBuilder getMapping() throws IOException {
+ XContentBuilder xContentBuilder = XContentFactory.jsonBuilder().startObject().startObject("type1")
+ .startObject("properties").startObject("location").field("type", "geo_point");
+ xContentBuilder.endObject().endObject().endObject().endObject();
+ return xContentBuilder;
+ }
+}
+
diff --git a/server/src/internalClusterTest/java/org/elasticsearch/search/geo/GeoBoundingBoxQueryGeoShapeIT.java b/server/src/internalClusterTest/java/org/elasticsearch/search/geo/GeoBoundingBoxQueryGeoShapeIT.java
new file mode 100644
index 0000000000000..49716a76f17e6
--- /dev/null
+++ b/server/src/internalClusterTest/java/org/elasticsearch/search/geo/GeoBoundingBoxQueryGeoShapeIT.java
@@ -0,0 +1,40 @@
+/*
+ * Licensed to Elasticsearch under one or more contributor
+ * license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright
+ * ownership. Elasticsearch licenses this file to you under
+ * the Apache License, Version 2.0 (the "License"); you may
+ * not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.elasticsearch.search.geo;
+
+import org.elasticsearch.common.xcontent.XContentBuilder;
+import org.elasticsearch.common.xcontent.XContentFactory;
+
+import java.io.IOException;
+
+public class GeoBoundingBoxQueryGeoShapeIT extends AbstractGeoBoundingBoxQueryIT {
+
+ @Override
+ public XContentBuilder getMapping() throws IOException {
+ XContentBuilder xContentBuilder = XContentFactory.jsonBuilder().startObject().startObject("type1")
+ .startObject("properties").startObject("location").field("type", "geo_shape");
+ if (randomBoolean()) {
+ xContentBuilder.field("strategy", "recursive");
+ }
+ xContentBuilder.endObject().endObject().endObject().endObject();
+ return xContentBuilder;
+ }
+}
+
diff --git a/server/src/internalClusterTest/java/org/elasticsearch/search/geo/GeoBoundingBoxQueryIT.java b/server/src/internalClusterTest/java/org/elasticsearch/search/geo/GeoBoundingBoxQueryIT.java
deleted file mode 100644
index 6b5f4b2b22bcd..0000000000000
--- a/server/src/internalClusterTest/java/org/elasticsearch/search/geo/GeoBoundingBoxQueryIT.java
+++ /dev/null
@@ -1,249 +0,0 @@
-/*
- * Licensed to Elasticsearch under one or more contributor
- * license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright
- * ownership. Elasticsearch licenses this file to you under
- * the Apache License, Version 2.0 (the "License"); you may
- * not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-package org.elasticsearch.search.geo;
-
-import org.elasticsearch.Version;
-import org.elasticsearch.action.search.SearchResponse;
-import org.elasticsearch.cluster.metadata.IndexMetadata;
-import org.elasticsearch.common.settings.Settings;
-import org.elasticsearch.common.xcontent.XContentBuilder;
-import org.elasticsearch.common.xcontent.XContentFactory;
-import org.elasticsearch.index.query.GeoValidationMethod;
-import org.elasticsearch.search.SearchHit;
-import org.elasticsearch.test.ESIntegTestCase;
-import org.elasticsearch.test.VersionUtils;
-
-import static org.elasticsearch.action.support.WriteRequest.RefreshPolicy.IMMEDIATE;
-import static org.elasticsearch.common.xcontent.XContentFactory.jsonBuilder;
-import static org.elasticsearch.index.query.QueryBuilders.boolQuery;
-import static org.elasticsearch.index.query.QueryBuilders.geoBoundingBoxQuery;
-import static org.elasticsearch.index.query.QueryBuilders.termQuery;
-import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertAcked;
-import static org.hamcrest.Matchers.anyOf;
-import static org.hamcrest.Matchers.equalTo;
-
-public class GeoBoundingBoxQueryIT extends ESIntegTestCase {
-
- @Override
- protected boolean forbidPrivateIndexSettings() {
- return false;
- }
-
- public void testSimpleBoundingBoxTest() throws Exception {
- Version version = VersionUtils.randomVersionBetween(random(), Version.V_6_0_0,
- Version.CURRENT);
- Settings settings = Settings.builder().put(IndexMetadata.SETTING_VERSION_CREATED, version).build();
- XContentBuilder xContentBuilder = XContentFactory.jsonBuilder().startObject().startObject("type1")
- .startObject("properties").startObject("location").field("type", "geo_point");
- xContentBuilder.endObject().endObject().endObject().endObject();
- assertAcked(prepareCreate("test").setSettings(settings).addMapping("type1", xContentBuilder));
- ensureGreen();
-
- client().prepareIndex("test", "type1", "1").setSource(jsonBuilder().startObject()
- .field("name", "New York")
- .startObject("location").field("lat", 40.7143528).field("lon", -74.0059731).endObject()
- .endObject()).get();
-
- // to NY: 5.286 km
- client().prepareIndex("test", "type1", "2").setSource(jsonBuilder().startObject()
- .field("name", "Times Square")
- .startObject("location").field("lat", 40.759011).field("lon", -73.9844722).endObject()
- .endObject()).get();
-
- // to NY: 0.4621 km
- client().prepareIndex("test", "type1", "3").setSource(jsonBuilder().startObject()
- .field("name", "Tribeca")
- .startObject("location").field("lat", 40.718266).field("lon", -74.007819).endObject()
- .endObject()).get();
-
- // to NY: 1.055 km
- client().prepareIndex("test", "type1", "4").setSource(jsonBuilder().startObject()
- .field("name", "Wall Street")
- .startObject("location").field("lat", 40.7051157).field("lon", -74.0088305).endObject()
- .endObject()).get();
-
- // to NY: 1.258 km
- client().prepareIndex("test", "type1", "5").setSource(jsonBuilder().startObject()
- .field("name", "Soho")
- .startObject("location").field("lat", 40.7247222).field("lon", -74).endObject()
- .endObject()).get();
-
- // to NY: 2.029 km
- client().prepareIndex("test", "type1", "6").setSource(jsonBuilder().startObject()
- .field("name", "Greenwich Village")
- .startObject("location").field("lat", 40.731033).field("lon", -73.9962255).endObject()
- .endObject()).get();
-
- // to NY: 8.572 km
- client().prepareIndex("test", "type1", "7").setSource(jsonBuilder().startObject()
- .field("name", "Brooklyn")
- .startObject("location").field("lat", 40.65).field("lon", -73.95).endObject()
- .endObject()).get();
-
- client().admin().indices().prepareRefresh().get();
-
- SearchResponse searchResponse = client().prepareSearch() // from NY
- .setQuery(geoBoundingBoxQuery("location").setCorners(40.73, -74.1, 40.717, -73.99))
- .get();
- assertThat(searchResponse.getHits().getTotalHits().value, equalTo(2L));
- assertThat(searchResponse.getHits().getHits().length, equalTo(2));
- for (SearchHit hit : searchResponse.getHits()) {
- assertThat(hit.getId(), anyOf(equalTo("1"), equalTo("3"), equalTo("5")));
- }
-
- searchResponse = client().prepareSearch() // from NY
- .setQuery(geoBoundingBoxQuery("location").setCorners(40.73, -74.1, 40.717, -73.99).type("indexed"))
- .get();
- assertThat(searchResponse.getHits().getTotalHits().value, equalTo(2L));
- assertThat(searchResponse.getHits().getHits().length, equalTo(2));
- for (SearchHit hit : searchResponse.getHits()) {
- assertThat(hit.getId(), anyOf(equalTo("1"), equalTo("3"), equalTo("5")));
- }
- }
-
- public void testLimit2BoundingBox() throws Exception {
- Version version = VersionUtils.randomVersionBetween(random(), Version.V_6_0_0,
- Version.CURRENT);
- Settings settings = Settings.builder().put(IndexMetadata.SETTING_VERSION_CREATED, version).build();
- XContentBuilder xContentBuilder = XContentFactory.jsonBuilder().startObject().startObject("type1")
- .startObject("properties").startObject("location").field("type", "geo_point");
- xContentBuilder.endObject().endObject().endObject().endObject();
- assertAcked(prepareCreate("test").setSettings(settings).addMapping("type1", xContentBuilder));
- ensureGreen();
-
- client().prepareIndex("test", "type1", "1").setSource(jsonBuilder().startObject()
- .field("userid", 880)
- .field("title", "Place in Stockholm")
- .startObject("location").field("lat", 59.328355000000002).field("lon", 18.036842).endObject()
- .endObject())
- .setRefreshPolicy(IMMEDIATE)
- .get();
-
- client().prepareIndex("test", "type1", "2").setSource(jsonBuilder().startObject()
- .field("userid", 534)
- .field("title", "Place in Montreal")
- .startObject("location").field("lat", 45.509526999999999).field("lon", -73.570986000000005).endObject()
- .endObject())
- .setRefreshPolicy(IMMEDIATE)
- .get();
-
- SearchResponse searchResponse = client().prepareSearch()
- .setQuery(
- boolQuery().must(termQuery("userid", 880)).filter(
- geoBoundingBoxQuery("location").setCorners(74.579421999999994, 143.5, -66.668903999999998, 113.96875))
- ).get();
- assertThat(searchResponse.getHits().getTotalHits().value, equalTo(1L));
- searchResponse = client().prepareSearch()
- .setQuery(
- boolQuery().must(termQuery("userid", 880)).filter(
- geoBoundingBoxQuery("location").setCorners(74.579421999999994, 143.5, -66.668903999999998, 113.96875)
- .type("indexed"))
- ).get();
- assertThat(searchResponse.getHits().getTotalHits().value, equalTo(1L));
-
- searchResponse = client().prepareSearch()
- .setQuery(
- boolQuery().must(termQuery("userid", 534)).filter(
- geoBoundingBoxQuery("location").setCorners(74.579421999999994, 143.5, -66.668903999999998, 113.96875))
- ).get();
- assertThat(searchResponse.getHits().getTotalHits().value, equalTo(1L));
- searchResponse = client().prepareSearch()
- .setQuery(
- boolQuery().must(termQuery("userid", 534)).filter(
- geoBoundingBoxQuery("location").setCorners(74.579421999999994, 143.5, -66.668903999999998, 113.96875)
- .type("indexed"))
- ).get();
- assertThat(searchResponse.getHits().getTotalHits().value, equalTo(1L));
- }
-
- public void testCompleteLonRange() throws Exception {
- Version version = VersionUtils.randomVersionBetween(random(), Version.V_6_0_0,
- Version.CURRENT);
- Settings settings = Settings.builder().put(IndexMetadata.SETTING_VERSION_CREATED, version).build();
- XContentBuilder xContentBuilder = XContentFactory.jsonBuilder().startObject().startObject("type1")
- .startObject("properties").startObject("location").field("type", "geo_point");
- xContentBuilder.endObject().endObject().endObject().endObject();
- assertAcked(prepareCreate("test").setSettings(settings).addMapping("type1", xContentBuilder));
- ensureGreen();
-
- client().prepareIndex("test", "type1", "1").setSource(jsonBuilder().startObject()
- .field("userid", 880)
- .field("title", "Place in Stockholm")
- .startObject("location").field("lat", 59.328355000000002).field("lon", 18.036842).endObject()
- .endObject())
- .setRefreshPolicy(IMMEDIATE)
- .get();
-
- client().prepareIndex("test", "type1", "2").setSource(jsonBuilder().startObject()
- .field("userid", 534)
- .field("title", "Place in Montreal")
- .startObject("location").field("lat", 45.509526999999999).field("lon", -73.570986000000005).endObject()
- .endObject())
- .setRefreshPolicy(IMMEDIATE)
- .get();
-
- SearchResponse searchResponse = client().prepareSearch()
- .setQuery(
- geoBoundingBoxQuery("location").setValidationMethod(GeoValidationMethod.COERCE).setCorners(50, -180, -50, 180)
- ).get();
- assertThat(searchResponse.getHits().getTotalHits().value, equalTo(1L));
- searchResponse = client().prepareSearch()
- .setQuery(
- geoBoundingBoxQuery("location").setValidationMethod(GeoValidationMethod.COERCE).setCorners(50, -180, -50, 180)
- .type("indexed")
- ).get();
- assertThat(searchResponse.getHits().getTotalHits().value, equalTo(1L));
- searchResponse = client().prepareSearch()
- .setQuery(
- geoBoundingBoxQuery("location").setValidationMethod(GeoValidationMethod.COERCE).setCorners(90, -180, -90, 180)
- ).get();
- assertThat(searchResponse.getHits().getTotalHits().value, equalTo(2L));
- searchResponse = client().prepareSearch()
- .setQuery(
- geoBoundingBoxQuery("location").setValidationMethod(GeoValidationMethod.COERCE).setCorners(90, -180, -90, 180)
- .type("indexed")
- ).get();
- assertThat(searchResponse.getHits().getTotalHits().value, equalTo(2L));
-
- searchResponse = client().prepareSearch()
- .setQuery(
- geoBoundingBoxQuery("location").setValidationMethod(GeoValidationMethod.COERCE).setCorners(50, 0, -50, 360)
- ).get();
- assertThat(searchResponse.getHits().getTotalHits().value, equalTo(1L));
- searchResponse = client().prepareSearch()
- .setQuery(
- geoBoundingBoxQuery("location").setValidationMethod(GeoValidationMethod.COERCE).setCorners(50, 0, -50, 360)
- .type("indexed")
- ).get();
- assertThat(searchResponse.getHits().getTotalHits().value, equalTo(1L));
- searchResponse = client().prepareSearch()
- .setQuery(
- geoBoundingBoxQuery("location").setValidationMethod(GeoValidationMethod.COERCE).setCorners(90, 0, -90, 360)
- ).get();
- assertThat(searchResponse.getHits().getTotalHits().value, equalTo(2L));
- searchResponse = client().prepareSearch()
- .setQuery(
- geoBoundingBoxQuery("location").setValidationMethod(GeoValidationMethod.COERCE).setCorners(90, 0, -90, 360)
- .type("indexed")
- ).get();
- assertThat(searchResponse.getHits().getTotalHits().value, equalTo(2L));
- }
-}
-
diff --git a/server/src/main/java/org/elasticsearch/index/query/GeoBoundingBoxQueryBuilder.java b/server/src/main/java/org/elasticsearch/index/query/GeoBoundingBoxQueryBuilder.java
index df2f6b6e4267b..76a2218da3966 100644
--- a/server/src/main/java/org/elasticsearch/index/query/GeoBoundingBoxQueryBuilder.java
+++ b/server/src/main/java/org/elasticsearch/index/query/GeoBoundingBoxQueryBuilder.java
@@ -19,9 +19,6 @@
package org.elasticsearch.index.query;
-import org.apache.lucene.document.LatLonDocValuesField;
-import org.apache.lucene.document.LatLonPoint;
-import org.apache.lucene.search.IndexOrDocValuesQuery;
import org.apache.lucene.search.MatchNoDocsQuery;
import org.apache.lucene.search.Query;
import org.elasticsearch.ElasticsearchParseException;
@@ -31,13 +28,15 @@
import org.elasticsearch.common.geo.GeoBoundingBox;
import org.elasticsearch.common.geo.GeoPoint;
import org.elasticsearch.common.geo.GeoUtils;
+import org.elasticsearch.common.geo.ShapeRelation;
+import org.elasticsearch.common.geo.SpatialStrategy;
import org.elasticsearch.common.io.stream.StreamInput;
import org.elasticsearch.common.io.stream.StreamOutput;
import org.elasticsearch.common.xcontent.XContentBuilder;
import org.elasticsearch.common.xcontent.XContentParser;
import org.elasticsearch.geometry.Rectangle;
import org.elasticsearch.geometry.utils.Geohash;
-import org.elasticsearch.index.mapper.GeoPointFieldMapper.GeoPointFieldType;
+import org.elasticsearch.index.mapper.GeoShapeQueryable;
import org.elasticsearch.index.mapper.MappedFieldType;
import java.io.IOException;
@@ -309,11 +308,12 @@ public Query doToQuery(QueryShardContext context) {
if (ignoreUnmapped) {
return new MatchNoDocsQuery();
} else {
- throw new QueryShardException(context, "failed to find geo_point field [" + fieldName + "]");
+ throw new QueryShardException(context, "failed to find geo field [" + fieldName + "]");
}
}
- if (!(fieldType instanceof GeoPointFieldType)) {
- throw new QueryShardException(context, "field [" + fieldName + "] is not a geo_point field");
+ if (!(fieldType instanceof GeoShapeQueryable)) {
+ throw new QueryShardException(context,
+ "Field [" + fieldName + "] is of unsupported type [" + fieldType.typeName() + "] for [" + NAME + "] query");
}
QueryValidationException exception = checkLatLon();
@@ -338,15 +338,10 @@ public Query doToQuery(QueryShardContext context) {
}
}
- Query query = LatLonPoint.newBoxQuery(fieldType.name(), luceneBottomRight.getLat(), luceneTopLeft.getLat(),
- luceneTopLeft.getLon(), luceneBottomRight.getLon());
- if (fieldType.hasDocValues()) {
- Query dvQuery = LatLonDocValuesField.newSlowBoxQuery(fieldType.name(),
- luceneBottomRight.getLat(), luceneTopLeft.getLat(),
- luceneTopLeft.getLon(), luceneBottomRight.getLon());
- query = new IndexOrDocValuesQuery(query, dvQuery);
- }
- return query;
+ final GeoShapeQueryable geoShapeQueryable = (GeoShapeQueryable) fieldType;
+ final Rectangle rectangle =
+ new Rectangle(luceneTopLeft.getLon(), luceneBottomRight.getLon(), luceneTopLeft.getLat(), luceneBottomRight.getLat());
+ return geoShapeQueryable.geoShapeQuery(rectangle, fieldType.name(), SpatialStrategy.RECURSIVE, ShapeRelation.INTERSECTS, context);
}
@Override
diff --git a/server/src/main/java/org/elasticsearch/index/query/GeoDistanceQueryBuilder.java b/server/src/main/java/org/elasticsearch/index/query/GeoDistanceQueryBuilder.java
index f4c0da2c5256a..527e927299d51 100644
--- a/server/src/main/java/org/elasticsearch/index/query/GeoDistanceQueryBuilder.java
+++ b/server/src/main/java/org/elasticsearch/index/query/GeoDistanceQueryBuilder.java
@@ -19,9 +19,6 @@
package org.elasticsearch.index.query;
-import org.apache.lucene.document.LatLonDocValuesField;
-import org.apache.lucene.document.LatLonPoint;
-import org.apache.lucene.search.IndexOrDocValuesQuery;
import org.apache.lucene.search.MatchNoDocsQuery;
import org.apache.lucene.search.Query;
import org.elasticsearch.common.ParseField;
@@ -30,12 +27,15 @@
import org.elasticsearch.common.geo.GeoDistance;
import org.elasticsearch.common.geo.GeoPoint;
import org.elasticsearch.common.geo.GeoUtils;
+import org.elasticsearch.common.geo.ShapeRelation;
+import org.elasticsearch.common.geo.SpatialStrategy;
import org.elasticsearch.common.io.stream.StreamInput;
import org.elasticsearch.common.io.stream.StreamOutput;
import org.elasticsearch.common.unit.DistanceUnit;
import org.elasticsearch.common.xcontent.XContentBuilder;
import org.elasticsearch.common.xcontent.XContentParser;
-import org.elasticsearch.index.mapper.GeoPointFieldMapper.GeoPointFieldType;
+import org.elasticsearch.geometry.Circle;
+import org.elasticsearch.index.mapper.GeoShapeQueryable;
import org.elasticsearch.index.mapper.MappedFieldType;
import java.io.IOException;
@@ -232,12 +232,13 @@ protected Query doToQuery(QueryShardContext shardContext) throws IOException {
if (ignoreUnmapped) {
return new MatchNoDocsQuery();
} else {
- throw new QueryShardException(shardContext, "failed to find geo_point field [" + fieldName + "]");
+ throw new QueryShardException(shardContext, "failed to find geo field [" + fieldName + "]");
}
}
- if (!(fieldType instanceof GeoPointFieldType)) {
- throw new QueryShardException(shardContext, "field [" + fieldName + "] is not a geo_point field");
+ if (!(fieldType instanceof GeoShapeQueryable)) {
+ throw new QueryShardException(shardContext,
+ "Field [" + fieldName + "] is of unsupported type [" + fieldType.typeName() + "] for [" + NAME + "] query");
}
QueryValidationException exception = checkLatLon();
@@ -249,12 +250,11 @@ protected Query doToQuery(QueryShardContext shardContext) throws IOException {
GeoUtils.normalizePoint(center, true, true);
}
- Query query = LatLonPoint.newDistanceQuery(fieldType.name(), center.lat(), center.lon(), this.distance);
- if (fieldType.hasDocValues()) {
- Query dvQuery = LatLonDocValuesField.newSlowDistanceQuery(fieldType.name(), center.lat(), center.lon(), this.distance);
- query = new IndexOrDocValuesQuery(query, dvQuery);
- }
- return query;
+ final GeoShapeQueryable geoShapeQueryable = (GeoShapeQueryable) fieldType;
+ final Circle circle =
+ new Circle(center.lon(), center.lat(), this.distance);
+ return geoShapeQueryable.geoShapeQuery(circle, fieldType.name(),
+ SpatialStrategy.RECURSIVE, ShapeRelation.INTERSECTS, shardContext);
}
@Override
diff --git a/server/src/test/java/org/elasticsearch/index/query/GeoBoundingBoxQueryBuilderTests.java b/server/src/test/java/org/elasticsearch/index/query/GeoBoundingBoxQueryBuilderTests.java
index c4fa6a3cc2371..9894b7d002361 100644
--- a/server/src/test/java/org/elasticsearch/index/query/GeoBoundingBoxQueryBuilderTests.java
+++ b/server/src/test/java/org/elasticsearch/index/query/GeoBoundingBoxQueryBuilderTests.java
@@ -25,8 +25,12 @@
import org.apache.lucene.search.MatchNoDocsQuery;
import org.apache.lucene.search.Query;
import org.elasticsearch.ElasticsearchParseException;
+import org.elasticsearch.Version;
import org.elasticsearch.common.geo.GeoPoint;
import org.elasticsearch.common.geo.GeoUtils;
+import org.elasticsearch.index.mapper.GeoPointFieldMapper;
+import org.elasticsearch.index.mapper.GeoShapeFieldMapper;
+import org.elasticsearch.index.mapper.LegacyGeoShapeFieldMapper;
import org.elasticsearch.index.mapper.MappedFieldType;
import org.elasticsearch.test.AbstractQueryTestCase;
import org.elasticsearch.test.geo.RandomShapeGenerator;
@@ -45,7 +49,7 @@ public class GeoBoundingBoxQueryBuilderTests extends AbstractQueryTestCase qb.toQuery(context));
- assertEquals("failed to find geo_point field [" + qb.fieldName() + "]", e.getMessage());
+ assertEquals("failed to find geo field [" + qb.fieldName() + "]", e.getMessage());
}
public void testBrokenCoordinateCannotBeSet() {
@@ -206,10 +210,11 @@ public void testStrictnessDefault() {
@Override
protected void doAssertLuceneQuery(GeoBoundingBoxQueryBuilder queryBuilder, Query query, QueryShardContext context)
throws IOException {
- MappedFieldType fieldType = context.getFieldType(queryBuilder.fieldName());
+ final MappedFieldType fieldType = context.getFieldType(queryBuilder.fieldName());
if (fieldType == null) {
assertTrue("Found no indexed geo query.", query instanceof MatchNoDocsQuery);
- } else if (query instanceof IndexOrDocValuesQuery) { // TODO: remove the if statement once we always use LatLonPoint
+ } else if (fieldType instanceof GeoPointFieldMapper.GeoPointFieldType) {
+ assertEquals(IndexOrDocValuesQuery.class, query.getClass());
Query indexQuery = ((IndexOrDocValuesQuery) query).getIndexQuery();
String expectedFieldName = expectedFieldName(queryBuilder.fieldName());
assertEquals(LatLonPoint.newBoxQuery(expectedFieldName,
@@ -223,6 +228,12 @@ protected void doAssertLuceneQuery(GeoBoundingBoxQueryBuilder queryBuilder, Quer
queryBuilder.topLeft().lat(),
queryBuilder.topLeft().lon(),
queryBuilder.bottomRight().lon()), dvQuery);
+ } else {
+ if (context.indexVersionCreated().before(Version.V_6_6_0)) {
+ assertEquals(LegacyGeoShapeFieldMapper.GeoShapeFieldType.class, fieldType.getClass());
+ } else {
+ assertEquals(GeoShapeFieldMapper.GeoShapeFieldType.class, fieldType.getClass());
+ }
}
}
@@ -535,6 +546,6 @@ public void testIgnoreUnmapped() throws IOException {
final GeoBoundingBoxQueryBuilder failingQueryBuilder = new GeoBoundingBoxQueryBuilder("unmapped").setCorners(1.0, 0.0, 0.0, 1.0);
failingQueryBuilder.ignoreUnmapped(false);
QueryShardException e = expectThrows(QueryShardException.class, () -> failingQueryBuilder.toQuery(shardContext));
- assertThat(e.getMessage(), containsString("failed to find geo_point field [unmapped]"));
+ assertThat(e.getMessage(), containsString("failed to find geo field [unmapped]"));
}
}
diff --git a/server/src/test/java/org/elasticsearch/index/query/GeoDistanceQueryBuilderTests.java b/server/src/test/java/org/elasticsearch/index/query/GeoDistanceQueryBuilderTests.java
index dfb8211463ea5..9ef07fd078a3c 100644
--- a/server/src/test/java/org/elasticsearch/index/query/GeoDistanceQueryBuilderTests.java
+++ b/server/src/test/java/org/elasticsearch/index/query/GeoDistanceQueryBuilderTests.java
@@ -24,10 +24,15 @@
import org.apache.lucene.search.IndexOrDocValuesQuery;
import org.apache.lucene.search.MatchNoDocsQuery;
import org.apache.lucene.search.Query;
+import org.elasticsearch.Version;
import org.elasticsearch.common.ParsingException;
import org.elasticsearch.common.geo.GeoDistance;
import org.elasticsearch.common.geo.GeoPoint;
import org.elasticsearch.common.unit.DistanceUnit;
+import org.elasticsearch.index.mapper.GeoPointFieldMapper;
+import org.elasticsearch.index.mapper.GeoShapeFieldMapper;
+import org.elasticsearch.index.mapper.LegacyGeoShapeFieldMapper;
+import org.elasticsearch.index.mapper.MappedFieldType;
import org.elasticsearch.test.AbstractQueryTestCase;
import org.elasticsearch.test.geo.RandomShapeGenerator;
import org.locationtech.spatial4j.shape.Point;
@@ -42,7 +47,7 @@ public class GeoDistanceQueryBuilderTests extends AbstractQueryTestCase failingQueryBuilder.toQuery(shardContext));
- assertThat(e.getMessage(), containsString("failed to find geo_point field [unmapped]"));
+ assertThat(e.getMessage(), containsString("failed to find geo field [unmapped]"));
}
public void testParseFailsWithMultipleFields() throws IOException {
diff --git a/x-pack/plugin/src/test/resources/rest-api-spec/test/runtime_fields/100_geo_point.yml b/x-pack/plugin/src/test/resources/rest-api-spec/test/runtime_fields/100_geo_point.yml
index 6803b79c79ea7..328470c806de4 100644
--- a/x-pack/plugin/src/test/resources/rest-api-spec/test/runtime_fields/100_geo_point.yml
+++ b/x-pack/plugin/src/test/resources/rest-api-spec/test/runtime_fields/100_geo_point.yml
@@ -86,6 +86,23 @@ setup:
---
"geo bounding box query":
+ - do:
+ search:
+ index: locations
+ body:
+ query:
+ geo_bounding_box:
+ location_from_source:
+ top_left:
+ lat: 10
+ lon: -10
+ bottom_right:
+ lat: -10
+ lon: 10
+ - match: {hits.total.value: 1}
+
+---
+"geo shape query":
- do:
search:
index: locations
@@ -98,6 +115,20 @@ setup:
coordinates: [ [ -10, 10 ], [ 10, -10 ] ]
- match: {hits.total.value: 1}
+---
+"geo distance query":
+ - do:
+ search:
+ index: locations
+ body:
+ query:
+ geo_distance:
+ distance: "2000km"
+ location_from_source:
+ lat: 0
+ lon: 0
+ - match: {hits.total.value: 1}
+
---
"bounds agg":
- do: