Skip to content

perf: pre-filter geoFeatures org units by geometry (#24279) [2.42]#24492

Merged
jason-p-pickering merged 1 commit into
2.42from
perf/geofeatures-geom-prefilter-43_2.42
Jul 23, 2026
Merged

perf: pre-filter geoFeatures org units by geometry (#24279) [2.42]#24492
jason-p-pickering merged 1 commit into
2.42from
perf/geofeatures-geom-prefilter-43_2.42

Conversation

@jason-p-pickering

Copy link
Copy Markdown
Contributor

Summary

Backport of #24279 to 2.42.

geoFeatures resolves the ou dimension into full OrganisationUnit entities, then discards every unit without geometry in-memory. On a large hierarchy (Nigeria prod: ~255k level-5 units, all null-geometry) this hydrates a quarter-million entities — ~7.6s CPU and ~4.7 GB allocated — only to return [].

This threads an optional geometryOnly flag from DataQueryRequest through DimensionalObjectProvider and OrganisationUnitService down to HibernateOrganisationUnitStore, which appends and o.geometry is not null. Default off, so all other callers dispatch the original methods unchanged. Skipped in geoJsonAttribute (coordinateField) mode, where coordinates come from an attribute and the geometry column may be null. The in-memory filter remains the precise final gate.

When the geometry-filtered resolution is empty, the E7143 empty-dimension guard is suppressed so geoFeatures still returns 200 [] rather than an error.

Validated on production (Nigeria, deployed on 2.40): a comparable high-level layer dropped from ~8.6s/4.7GB to 14ms/747KB.

Backport notes

Cherry-pick of 2c7ee45 onto 2.42 hit conflicts because 2.42 lacks a master-only feature (stage-specific category/COGS dimension resolution in DefaultDataQueryService) — resolved by keeping 2.42's existing dispatch path and applying only the geometry-only wiring. A related type mismatch in DimensionalObjectProvider.getOrgUnitDimension (auto-merged without conflict markers but broke compilation) was fixed by aligning the new overload's return type with 2.42's existing BaseDimensionalObject signature.

Test plan

  • dhis-service-analytics and dhis-web-api (main + test sources) compile cleanly
  • spotless:check passes
  • CI

Co-Authored-By: Claude Opus 4.8 (1M context) noreply@anthropic.com

* perf: pre-filter geoFeatures org units by geometry

geoFeatures resolves the `ou` dimension into full OrganisationUnit
entities, then discards every unit without geometry in-memory. On a
large hierarchy (Nigeria prod: ~255k level-5 units, all null-geometry)
this hydrates a quarter-million entities — ~7.6s CPU and ~4.7 GB
allocated — only to return [].

Thread an optional `geometryOnly` flag from DataQueryRequest through
DimensionalObjectProvider and OrganisationUnitService down to
HibernateOrganisationUnitStore, which appends `and o.geometry is not
null`. Default off, so all other callers dispatch the original 2-arg
methods unchanged. Skipped in geoJsonAttribute (coordinateField) mode,
where coordinates come from an attribute and the geometry column may be
null. The in-memory filter remains the precise final gate.

When the geometry-filtered resolution is empty, the E7143 empty-dimension
guard is suppressed so geoFeatures still returns 200 [] rather than an
error.

Validated on production (Nigeria, deployed on 2.40): a comparable
high-level layer dropped from ~8.6s/4.7GB to 14ms/747KB.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* refactor: bundle getDimension args into DimensionResolveOptions

The private getDimension dispatcher grew to 8 parameters when geometryOnly
was threaded through, tripping SonarQube java:S107 (>7 parameters). Bundle
the five resolution options (relativePeriodDate, displayProperty, allowNull,
inputIdScheme, geometryOnly) into a private DimensionResolveOptions record,
bringing the method to 4 parameters. Behaviour is unchanged; contained
entirely within DefaultDataQueryService.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@sonarqubecloud

Copy link
Copy Markdown

@jason-p-pickering
jason-p-pickering requested review from a team and stian-sandvold July 22, 2026 07:46
@david-mackessy
david-mackessy requested a review from a team July 23, 2026 07:28
@jason-p-pickering
jason-p-pickering merged commit 5a726ce into 2.42 Jul 23, 2026
14 checks passed
@jason-p-pickering
jason-p-pickering deleted the perf/geofeatures-geom-prefilter-43_2.42 branch July 23, 2026 17:45
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants