Skip to content

Three new simple but useful spatial functions - #144703

Merged
elasticsearchmachine merged 18 commits into
elastic:mainfrom
craigtaverner:three_spatial_functions
Mar 25, 2026
Merged

elasticsearchmachine merged 18 commits into
elastic:mainfrom
craigtaverner:three_spatial_functions

Conversation

@craigtaverner

@craigtaverner craigtaverner commented Mar 21, 2026 •

Copy link
Copy Markdown
Contributor

Three new simple but useful spatial functions, particularly when testing ST_CENTROID_AGG which takes topological dimension into account during aggregations:

  • ST_Dimension (topological dimension)
    • The topological dimension is 0 for points, 1 for lines and 2 for polygons. This is important in understanding how centroids are calculated in ST_CENTROID_AGG, where higher dimensions completely remove the contribution from lower ones.
    • See the PostGIS equivalent at https://postgis.net/docs/ST_Dimension.html
  • ST_GeometryType
  • ST_IsEmpty

The ST_GeometryType and ST_Dimension functions also include a specific optimization for point types, since they will always return a constant values for all non-null results. This had a noticable effect on the macro-benchmarks results for the geopoint track:

Task Without constant evaluator With constant evaluator Improvement
st-geometrytype-stats-esql 462.121 98.4184 80%
st-dimension-stats-esql 159.484 150.169 6%
st-isempty-stats-esql 124.098 126.023 0%

* ST_Dimension (topological dimension) as in https://postgis.net/docs/ST_Dimension.html
* ST_GeometryType (string name of geometry type) as in https://postgis.net/docs/ST_GeometryType.html
* ST_IsEmpty (boolean) as in https://postgis.net/docs/ST_IsEmpty.html
@craigtaverner
craigtaverner requested a review from a team as a code owner March 21, 2026 20:16
@craigtaverner craigtaverner added >enhancement :Analytics/Geo Indexing, search aggregations of geo points and shapes Team:Analytics Meta label for analytical engine team (ESQL/Aggs/Geo) :Analytics/ES|QL AKA ESQL labels Mar 21, 2026
@craigtaverner
craigtaverner requested review from ncordon and removed request for a team March 21, 2026 20:16
@elasticsearchmachine

Copy link
Copy Markdown
Collaborator

Pinging @elastic/es-analytical-engine (Team:Analytics)

@elasticsearchmachine

Copy link
Copy Markdown
Collaborator

Hi @craigtaverner, I've created a changelog YAML for you.

@github-actions

Copy link
Copy Markdown
Contributor

ℹ️ Important: Docs version tagging

👋 Thanks for updating the docs! Just a friendly reminder that our docs are now cumulative. This means all 9.x versions are documented on the same page and published off of the main branch, instead of creating separate pages for each minor version.

We use applies_to tags to mark version-specific features and changes.

Expand for a quick overview

When to use applies_to tags:

✅ At the page level to indicate which products/deployments the content applies to (mandatory)
✅ When features change state (e.g. preview, ga) in a specific version
✅ When availability differs across deployments and environments

What NOT to do:

❌ Don't remove or replace information that applies to an older version
❌ Don't add new information that applies to a specific version without an applies_to tag
❌ Don't forget that applies_to tags can be used at the page, section, and inline level

🤔 Need help?

@craigtaverner
craigtaverner requested a review from a team as a code owner March 21, 2026 20:58
craigtaverner and others added 7 commits March 21, 2026 22:06
This was previously a much larger change, based on double-checking that the constant block optimization actually made an improvement in macro benchmarks, which it did (a lot for ST_GEOMETRYTYPE and a small amount for ST_DIMENSION).
Comment thread docs/redirects.yml Outdated
Comment on lines +371 to +376
- to: 'reference/query-languages/esql/functions-operators/spatial-functions/st_geometrytype.md'
anchors: {'esql-st_geometrytype'}
- to: 'reference/query-languages/esql/functions-operators/spatial-functions/st_dimension.md'
anchors: {'esql-st_dimension'}
- to: 'reference/query-languages/esql/functions-operators/spatial-functions/st_isempty.md'
anchors: {'esql-st_isempty'}

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if these functions are new (e.g. docs content is not being moved from one location to another), then no redirects should be needed

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, removing them now.

@ncordon ncordon left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Left a few improvements but nothing major to correct

Comment on lines +227 to +229
for (Geometry geometry : collection) {
maxDimension = Math.max(maxDimension, geometry.visit(this));
}

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we could short circuit this is we are already at dimension 2?

if (maxDimension == 2) {
  break;
}


@Override
public long baseRamBytesUsed() {
return field.baseRamBytesUsed();

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Shouldn't we include the shallow size here?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good catch. I've changed to to look more like what we see in StDimensionFromWKBEvaluator.

case GEOMETRYCOLLECTION -> "ST_GeometryCollection";
case LINEARRING -> "ST_LineString";
case ENVELOPE -> "ST_Polygon";
case CIRCLE -> "ST_Point";

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We discussed changing this to be a line (probably a St_Polygon?)

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done! And I did a search for OGC compliance for the option of ST_Circle and that is not OGC compliant, so we stick with ST_Polygon.

BytesRef wkb = wkbBlock.getBytesRef(firstValueIndex + i, scratch);
Geometry geometry = UNSPECIFIED.wkbToGeometry(wkb);
int dimension = geometry.visit(DIMENSION_VISITOR);
maxDimension = Math.max(maxDimension, dimension);

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same here, we could short circuit in the case we've reached the max dimension true?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great idea. I added an extra condition to the for loop a few lines above.

@craigtaverner craigtaverner added the auto-merge-without-approval Automatically merge pull request when CI checks pass (NB doesn't wait for reviews!) label Mar 25, 2026
@elasticsearchmachine
elasticsearchmachine merged commit 3ba52bd into elastic:main Mar 25, 2026
36 checks passed
@craigtaverner
craigtaverner deleted the three_spatial_functions branch March 25, 2026 15:38
seanzatzdev pushed a commit to seanzatzdev/elasticsearch that referenced this pull request Mar 27, 2026
Three new simple but useful spatial functions, particularly when testing
`ST_CENTROID_AGG` which takes topological dimension into account during
aggregations:

* `ST_Dimension` (topological dimension)
  * The topological dimension is 0 for points, 1 for lines and 2 for polygons. This is important in understanding how centroids are calculated in ST_CENTROID_AGG, where higher dimensions completely remove the contribution from lower ones.
  * See the PostGIS equivalent at https://postgis.net/docs/ST_Dimension.html
* `ST_GeometryType`
  * A string name of the geometry type: ST_Point, ST_LineString, etc.
  * See the PostGIS equivalent at https://postgis.net/docs/ST_GeometryType.html
* `ST_IsEmpty`
  * A boolean flag for whether the geometry is empty or not
  * See PostGIS equivalent at https://postgis.net/docs/ST_IsEmpty.html

The `ST_GeometryType` and `ST_Dimension` functions also include a
specific optimization for point types, since they will always return a
constant values for all non-null results. This had a noticable effect on
the macro-benchmarks results for the geopoint track:

| Task | Without constant evaluator | With constant evaluator |
Improvement | | --- | --- | --- | --- | | st-geometrytype-stats-esql |  
462.121         |     98.4184  | 80% | |  st-dimension-stats-esql |  
159.484       |     150.169 |  6% | | st-isempty-stats-esql |   124.098 
|     126.023 | 0% |
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

:Analytics/ES|QL AKA ESQL :Analytics/Geo Indexing, search aggregations of geo points and shapes auto-merge-without-approval Automatically merge pull request when CI checks pass (NB doesn't wait for reviews!) >enhancement Team:Analytics Meta label for analytical engine team (ESQL/Aggs/Geo) v9.4.0

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants