From 68a6722f87868276d1d47a376fb29d802f092cc2 Mon Sep 17 00:00:00 2001 From: iverase Date: Wed, 8 Mar 2023 14:15:19 +0100 Subject: [PATCH 1/4] Add support for searchable docvalue only geo_shape --- .../mapping/types/geo-shape.asciidoc | 8 ++ .../GeoShapeWithDocValuesFieldMapper.java | 14 +- .../test/spatial/110_geo_shape_parameters.yml | 127 ++++++++++++++++++ 3 files changed, 145 insertions(+), 4 deletions(-) create mode 100644 x-pack/plugin/src/yamlRestTest/resources/rest-api-spec/test/spatial/110_geo_shape_parameters.yml diff --git a/docs/reference/mapping/types/geo-shape.asciidoc b/docs/reference/mapping/types/geo-shape.asciidoc index 1d1da12ccf95f..00d575b6951ef 100644 --- a/docs/reference/mapping/types/geo-shape.asciidoc +++ b/docs/reference/mapping/types/geo-shape.asciidoc @@ -70,6 +70,14 @@ and reject the whole document. |`coerce` |If `true` unclosed linear rings in polygons will be automatically closed. | `false` +|`index` |Should the field be quickly searchable? Accepts `true` (default) and `false`. +Fields that only have <> enabled can still be queried, albeit slower. +| `true` + +|`doc_values` |Should the field be stored on disk in a column-stride fashion, +so that it can later be used for aggregations, or scripting? +| `true` + |======================================================================= diff --git a/x-pack/plugin/spatial/src/main/java/org/elasticsearch/xpack/spatial/index/mapper/GeoShapeWithDocValuesFieldMapper.java b/x-pack/plugin/spatial/src/main/java/org/elasticsearch/xpack/spatial/index/mapper/GeoShapeWithDocValuesFieldMapper.java index d7285823d6bb0..6a86eb0e6f5aa 100644 --- a/x-pack/plugin/spatial/src/main/java/org/elasticsearch/xpack/spatial/index/mapper/GeoShapeWithDocValuesFieldMapper.java +++ b/x-pack/plugin/spatial/src/main/java/org/elasticsearch/xpack/spatial/index/mapper/GeoShapeWithDocValuesFieldMapper.java @@ -197,6 +197,7 @@ public String typeName() { @Override public Query geoShapeQuery(SearchExecutionContext context, String fieldName, ShapeRelation relation, LatLonGeometry... geometries) { + failIfNotIndexedNorDocValuesFallback(context); // CONTAINS queries are not supported by VECTOR strategy for indices created before version 7.5.0 (Lucene 8.3.0) if (relation == ShapeRelation.CONTAINS && context.indexVersionCreated().before(Version.V_7_5_0)) { throw new QueryShardException( @@ -204,10 +205,15 @@ public Query geoShapeQuery(SearchExecutionContext context, String fieldName, Sha ShapeRelation.CONTAINS + " query relation not supported for Field [" + fieldName + "]." ); } - Query query = LatLonShape.newGeometryQuery(fieldName, relation.getLuceneRelation(), geometries); - if (hasDocValues()) { - final Query queryDocValues = new LatLonShapeDocValuesQuery(fieldName, relation.getLuceneRelation(), geometries); - query = new IndexOrDocValuesQuery(query, queryDocValues); + Query query; + if (isIndexed()) { + query = LatLonShape.newGeometryQuery(fieldName, relation.getLuceneRelation(), geometries); + if (hasDocValues()) { + final Query queryDocValues = new LatLonShapeDocValuesQuery(fieldName, relation.getLuceneRelation(), geometries); + query = new IndexOrDocValuesQuery(query, queryDocValues); + } + } else { + query = new LatLonShapeDocValuesQuery(fieldName, relation.getLuceneRelation(), geometries); } return query; } diff --git a/x-pack/plugin/src/yamlRestTest/resources/rest-api-spec/test/spatial/110_geo_shape_parameters.yml b/x-pack/plugin/src/yamlRestTest/resources/rest-api-spec/test/spatial/110_geo_shape_parameters.yml new file mode 100644 index 0000000000000..6ebbe01c92bc2 --- /dev/null +++ b/x-pack/plugin/src/yamlRestTest/resources/rest-api-spec/test/spatial/110_geo_shape_parameters.yml @@ -0,0 +1,127 @@ +setup: + - do: + indices.create: + index: shapes + body: + mappings: + properties: + default: + type: geo_shape + no_doc_values: + type: geo_shape + doc_values: false + no_index: + type: geo_shape + index: false + no_doc_values_no_index: + type: geo_shape + doc_values: false + index: false + - do: + bulk: + refresh: true + body: + - index: + _index: shapes + _id: 1 + - '{"default": "POINT(4.912350 52.374081)", "no_doc_values": "POINT(4.912350 52.374081)", "no_index": "POINT(4.912350 52.374081)", "no_doc_values_no_index": "POINT(4.912350 52.374081)"}' + - index: + _index: shapes + _id: 2 + - '{"default": "POINT(2.327000 48.860000)", "no_doc_values": "POINT(2.327000 48.860000)", "no_index": "POINT(2.327000 48.860000)", "no_doc_values_no_index": "POINT(2.327000 48.860000)"}' + - do: + indices.refresh: {} + +--- +"Test field mapping": + - do: + indices.get_mapping: + index: shapes + + - match: {shapes.mappings.properties.default.type: geo_shape } + - match: {shapes.mappings.properties.no_doc_values.type: geo_shape } + - match: {shapes.mappings.properties.no_doc_values.doc_values: false } + - match: {shapes.mappings.properties.no_index.type: geo_shape } + - match: {shapes.mappings.properties.no_index.index: false } + - match: {shapes.mappings.properties.no_doc_values_no_index.type: geo_shape } + - match: {shapes.mappings.properties.no_doc_values_no_index.index: false } + - match: {shapes.mappings.properties.no_doc_values_no_index.doc_values: false } + +--- +"Test query default field": + - do: + search: + index: shapes + body: + query: + geo_bounding_box: + default: + top_left: + lat: 55 + lon: 4 + bottom_right: + lat: 50 + lon: 5 + + - match: { hits.total.value: 1 } + + +--- +"Test query no_doc_values field": + - do: + search: + index: shapes + body: + query: + geo_bounding_box: + no_doc_values: + top_left: + lat: 55 + lon: 4 + bottom_right: + lat: 50 + lon: 5 + + - match: { hits.total.value: 1 } + + +--- +"Test query no_index field": + - do: + search: + index: shapes + body: + query: + geo_bounding_box: + no_index: + top_left: + lat: 55 + lon: 4 + bottom_right: + lat: 50 + lon: 5 + + - match: { hits.total.value: 1 } + +--- +"Test query no_doc_values_no_index field": + - do: + catch: bad_request + search: + index: shapes + body: + query: + geo_bounding_box: + no_doc_values_no_index: + top_left: + lat: 55 + lon: 4 + bottom_right: + lat: 50 + lon: 5 + + - match: {error.type: search_phase_execution_exception} + - match: {error.reason: "all shards failed"} + - match: {error.phase: query} + - match: {error.failed_shards.0.reason.type: query_shard_exception} + - match: {error.failed_shards.0.reason.reason: "failed to create query: Cannot search on field [no_doc_values_no_index] since it is not indexed nor has doc values."} From 255c5a7da704af634e442551fe8c9f138fe7cfd4 Mon Sep 17 00:00:00 2001 From: Ignacio Vera Date: Wed, 8 Mar 2023 14:20:54 +0100 Subject: [PATCH 2/4] Update docs/changelog/94396.yaml --- docs/changelog/94396.yaml | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 docs/changelog/94396.yaml diff --git a/docs/changelog/94396.yaml b/docs/changelog/94396.yaml new file mode 100644 index 0000000000000..58cc074e895ab --- /dev/null +++ b/docs/changelog/94396.yaml @@ -0,0 +1,5 @@ +pr: 94396 +summary: Allow docvalues-only search on `geo_shape` +area: Geo +type: enhancement +issues: [] From aa1e2a5894d884dd99920ffd648b38e53fae4f30 Mon Sep 17 00:00:00 2001 From: iverase Date: Wed, 8 Mar 2023 14:26:00 +0100 Subject: [PATCH 3/4] typo --- docs/reference/mapping/types/geo-shape.asciidoc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/reference/mapping/types/geo-shape.asciidoc b/docs/reference/mapping/types/geo-shape.asciidoc index 00d575b6951ef..37ef340733932 100644 --- a/docs/reference/mapping/types/geo-shape.asciidoc +++ b/docs/reference/mapping/types/geo-shape.asciidoc @@ -75,7 +75,7 @@ Fields that only have <> enabled can still be queried, | `true` |`doc_values` |Should the field be stored on disk in a column-stride fashion, -so that it can later be used for aggregations, or scripting? +so that it can later be used for aggregations or scripting? | `true` |======================================================================= From 9f9fe1059645bfd49f2c9a95eed3a2541a8e4a20 Mon Sep 17 00:00:00 2001 From: iverase Date: Wed, 8 Mar 2023 15:03:00 +0100 Subject: [PATCH 4/4] fix test --- .../xpack/spatial/ingest/CircleProcessorTests.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/x-pack/plugin/spatial/src/test/java/org/elasticsearch/xpack/spatial/ingest/CircleProcessorTests.java b/x-pack/plugin/spatial/src/test/java/org/elasticsearch/xpack/spatial/ingest/CircleProcessorTests.java index 172cdeee2c83f..e9d12e99eaaf7 100644 --- a/x-pack/plugin/spatial/src/test/java/org/elasticsearch/xpack/spatial/ingest/CircleProcessorTests.java +++ b/x-pack/plugin/spatial/src/test/java/org/elasticsearch/xpack/spatial/ingest/CircleProcessorTests.java @@ -13,6 +13,7 @@ import org.apache.lucene.search.Query; import org.apache.lucene.store.Directory; import org.apache.lucene.tests.index.RandomIndexWriter; +import org.elasticsearch.Version; import org.elasticsearch.common.bytes.BytesReference; import org.elasticsearch.common.geo.GeoJson; import org.elasticsearch.common.geo.Orientation; @@ -210,6 +211,7 @@ public void testGeoShapeQueryAcrossDateline() throws IOException { SearchExecutionContext mockedContext = mock(SearchExecutionContext.class); when(mockedContext.getFieldType(any())).thenReturn(shapeType); + when(mockedContext.indexVersionCreated()).thenReturn(Version.CURRENT); Query sameShapeQuery = shapeType.geoShapeQuery(mockedContext, fieldName, ShapeRelation.INTERSECTS, geometry); Query pointOnDatelineQuery = shapeType.geoShapeQuery( mockedContext,