Skip to content

Map calculated value fields according to their configured element type - #488

Merged
kingjia90 merged 4 commits into
pimcore:2026.2from
andreaswagner-rnab:fix/calculated-value-element-type-mapping
Sep 16, 2026
Merged

kingjia90 merged 4 commits into
pimcore:2026.2from
andreaswagner-rnab:fix/calculated-value-element-type-mapping

Conversation

@andreaswagner-rnab

@andreaswagner-rnab andreaswagner-rnab commented Aug 5, 2026

Copy link
Copy Markdown
Contributor

Fixes pimcore/platform-version#293

Problem

Calculated value fields are always indexed with the generic text/keyword mapping, regardless of their configured element type (calculatedValue is registered on TextKeywordAdapter in field-definition-adapters.yml).

For a CalculatedValue field with elementType: 'boolean' this creates a text mapping with ngram/keyword/sort subfields in the search index. Term queries, aggregations and boolean filters on the field then behave like text search, and the Studio data object grid boolean filter on such a field stops working.

Reproduction

  1. Class definition with a CalculatedValue field configured with elementType: 'boolean'
  2. Run bin/console generic-data-index:update:index
  3. GET <index>/_mapping/field/standard_fields.<fieldname> returns text (with ngram/keyword/sort subfields) instead of boolean

Solution

Add a dedicated CalculatedValueAdapter that maps the field according to its configured element type:

elementType index mapping
boolean boolean
numeric double (via NumericMappingTrait, consistent with #510)
date date (strict_date_time_no_millis)
input / textarea / html (default) text/keyword (behavior unchanged)

Values are normalized per element type, since calculators are free to return loosely typed values (e.g. '0'/'1' strings from expression results, which a boolean mapping would reject). Date strings are parsed as well, since class calculators are typed to return strings and the query_store mode only yields strings. For the text-based element types the existing TextKeywordAdapter normalization (base64 src stripping) is preserved.

An upgrade note was added, since the mapping change requires generic-data-index:update:index + re-indexing to take effect.

Edit (maintainer): numeric maps as double instead of the originally proposed float, and date normalization also accepts strings — see this comment for details.

Covered by unit tests (CalculatedValueAdapterTest). Verified end-to-end on Elasticsearch 8.19: after this change generic-data-index:update:index creates the new index version with a boolean mapping and reindexing succeeds.

Copilot AI balanced review requested due to automatic review settings August 5, 2026 08:21
@pimcore-deployments
pimcore-deployments marked this pull request as draft August 5, 2026 08:21

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🟡 Changes recommended

Boolean string values such as 'false' are currently normalized to true.

Once you've addressed the issues Copilot identified, you can request another Copilot review.

This review doesn't count toward merge requirements. Sign up for the private preview to control whether Copilot approvals count.

Pull request overview

Adds element-type-aware indexing for calculated values.

Changes:

  • Adds boolean, numeric, date, and text mappings with normalization.
  • Registers the dedicated adapter.
  • Adds unit coverage for mappings and normalization.
File summaries
File Description
CalculatedValueAdapter.php Implements mapping and normalization.
field-definition-adapters.yml Registers the new adapter.
CalculatedValueAdapterTest.php Tests mappings and normalized values.
Review details
  • Files reviewed: 3/3 changed files
  • Comments generated: 1
  • Review effort level: Balanced

We're testing this review assessment. Please use 👍 or 👎 to tell us if it's correct.

Calculated value fields were always mapped as text/keyword regardless of
their configured element type. This made boolean, numeric and date
calculated values unusable for term queries, aggregations and range
filters in the search index.

Add a dedicated CalculatedValueAdapter that maps the field based on the
element type (boolean, numeric, date) and falls back to the existing
text/keyword mapping for the text-based element types (input, textarea,
html). Values are normalized accordingly, since calculators may return
loosely typed values.
A plain bool cast would index the literal 'false' (and values such as
'off'/'no') as true, silently reversing filters. Use FILTER_VALIDATE_BOOLEAN
with FILTER_NULL_ON_FAILURE so unrecognized values become null instead.
@andreaswagner-rnab
andreaswagner-rnab force-pushed the fix/calculated-value-element-type-mapping branch from aae95d9 to abd7cc9 Compare August 5, 2026 09:05
@andreaswagner-rnab
andreaswagner-rnab marked this pull request as ready for review August 5, 2026 09:05
@sonarqubecloud

sonarqubecloud Bot commented Aug 5, 2026

Copy link
Copy Markdown

@astapc
astapc requested a review from mcop1 August 10, 2026 05:16
kingjia90 and others added 2 commits September 15, 2026 13:38
Numeric calculated fields now map through NumericMappingTrait as 64-bit
double instead of 32-bit float, consistent with the Numeric/QuantityValue
adapters (pimcore#510), so large values are not collapsed by float32 rounding.

Date normalization also accepts date strings: class calculators are typed
to return strings and the query_store mode only ever yields strings, so
accepting only DateTimeInterface would silently drop most calculated date
values. Unparseable values degrade to null instead of failing the document.

Adds an upgrade note since the mapping change requires re-indexing.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@kingjia90

Copy link
Copy Markdown
Contributor

Thanks for the well-analyzed fix, including the reproduction and the filter_var follow-up — the approach (dedicated adapter, element-type-driven mapping, text fallback for the default types) is exactly right.

I verified the root cause (calculatedValue has been registered on TextKeywordAdapter since the initial adapter registration) and pushed two adjustments directly to your branch (maintainer edits are enabled), plus a branch update with the current 2026.2:

  1. numeric now maps as double via NumericMappingTrait instead of 32-bit float[Bug] Map numeric fields as long or double instead of float #510 recently moved all numeric mappings to long/double so large values don't collapse under float32 rounding; calculated fields have no integer flag, so they always get double.
  2. date normalization also parses date stringsCalculatorClassInterface::compute() is typed : string in core, and the query_store mode (added in [Feature] calculated_fields_index_mode: index calculated values from the query store #492 after this PR was opened) only ever yields strings, so accepting only DateTimeInterface would have silently dropped most calculated date values. Unparseable strings degrade to null instead of failing the whole document.
  3. Added an upgrade note (doc/01_Installation/02_Upgrade.md), since the mapping change requires generic-data-index:update:index + re-indexing to take effect.

Unit suite, PHPStan and php-cs-fixer are green locally on PHP 8.4.

@kingjia90 kingjia90 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Root cause confirmed (calculatedValue registered on TextKeywordAdapter since the initial registration, elementType never consulted). Fix sits at the right boundary, covers plain + localized calculated fields (LocalizedFieldsAdapter delegates mapping and normalization to the child adapter), keeps the default text/keyword behavior for input/textarea/html, and is covered by unit tests. With the double-mapping and date-string adjustments pushed on top, this is good to go once CI is green.

@kingjia90
kingjia90 requested a balanced review from Copilot September 15, 2026 11:38
@sonarqubecloud

Copy link
Copy Markdown

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🟡 Changes recommended

The numeric mapping is double, while the PR description and linked issue specify float.

Get a fresh assessment by requesting another Copilot review.

Review details
  • Files reviewed: 4/4 changed files
  • Comments generated: 1
  • Review effort level: Balanced

@kingjia90 kingjia90 added this to the 2026.2.9 milestone Sep 15, 2026
@kingjia90 kingjia90 assigned kingjia90 and unassigned kingjia90 Sep 15, 2026
@kingjia90
kingjia90 requested a balanced review from Copilot September 16, 2026 15:13
@kingjia90 kingjia90 self-assigned this Sep 16, 2026
@kingjia90
kingjia90 merged commit c3bff36 into pimcore:2026.2 Sep 16, 2026
25 checks passed
@github-actions github-actions Bot locked and limited conversation to collaborators Sep 16, 2026
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants