fix(os-search): honor track_total_hits and _score sort on the OpenSearch read path (#36501)#36557
Conversation
…rch read path (#36501) Two OS read-path gaps surfaced running the integration suite under migration phase 2 (reads from OpenSearch); both have a working ES reference implementation. - track_total_hits: OSIndexProperty.TRACK_TOTAL_HITS had no ES fallback key, so an existing ES_TRACK_TOTAL_HITS configuration was ignored under OS reads and OS always reported the full accurate count. Add the "ES_TRACK_TOTAL_HITS" fallback, matching the dual-key pattern used by USE_FILTERS_FOR_SEARCHING. (Fixes ESContentFactoryImplTest .Test_TrackHits_SearchCount under phase 2 — a gap tracked in #36320.) - _score sort: ContentFactoryIndexOperationsOS.addSorting, for sortBy=score, added only the secondary field sort and never a primary _score sort, so results were ordered by moddate and hit[0] was not the highest-scoring document. Add the _score DESC primary sort before the secondary field, mirroring ContentFactoryIndexOperationsES.addSorting. (Fixes ESContentFactoryImplTest.testScore under phase 2.) Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
Claude finished @fabrizzio-dotCMS's task in 2m 20s —— View job Rollback-Safety Analysis — PR #36557
Verdict: ✅ Safe to rollback — label Why: Both changes are pure query-construction logic evaluated at search time, not storage/schema/mapping changes:
No category in the reference doc applies: no |
|
Tick the box to add this pull request to the merge queue (same as
|
…36494) (dotCMS#36643) ## Proposed Changes Fixes dotCMS#36494. During the ES→OpenSearch migration, content queries sorting by relevance (`sort=score`) silently lost their ordering once reads switched to OpenSearch (Phase 2+): they came back in default `moddate desc` order instead of `_score` order. HTTP 200, plausible-looking hit set, wrong order — the kind of regression count-based parity checks can't catch. Root cause: `ContentFactoryIndexOperationsOS.addSorting`'s `sortBy.startsWith("score")` branch added only the secondary sort and never the primary `_score` sort. > **Note (post-rebase):** the core `_score`-sort fix has since landed on `main` via dotCMS#36501/dotCMS#36557 (`fix(os-search): honor track_total_hits and _score sort on the OpenSearch read path`), which added the same primary/secondary sort to this branch. After merging `main`, the **net contribution of this PR is now**: > 1. **`unmappedType(Date)` hardening** on the secondary sort, and > 2. the **regression tests** for `sort=score` (which `main` does not have). ### What this PR still changes **Production — `ContentFactoryIndexOperationsOS.addSorting`:** add `unmappedType(Date)` to the secondary field sort in the `score` branch, matching the scroll path (`OSContentletScrollImpl`). Without it, `sort=score <field>` fails on indices where the secondary field is not mapped, instead of degrading gracefully. Behavior for all other sort inputs is unchanged. ### Tests Added to `OpenSearchUpgradeSuite` (`ContentFactoryIndexOperationsOSIntegrationTest`) — new coverage not present on `main`: - `test_searchHits_sortByScore_shouldOrderByRelevanceNotModdate` — indexes docs so relevance order is the exact reverse of moddate order; asserts scores come back descending and the most-relevant doc is first (guards against the original regression). - `test_searchHits_sortByScore_secondaryOverride_shouldApplySecondarySort` — equal-score docs, `sort=score moddate asc`; asserts the secondary sort breaks the tie. ### Acceptance Criteria - [x] `addSorting` adds the primary `_score` (desc) sort in the `score` branch, secondary sort after it (now on `main` via dotCMS#36501/dotCMS#36557; preserved through the merge). - [x] Secondary sort uses `unmappedType(Date)` so `sort=score <field>` does not fail on indices missing that field. - [x] `sort=score` returns relevance ordering in Phase 2/3 (suite coverage). - [x] `sort=score <field> <dir>` secondary-sort override behaves correctly (suite coverage). - [x] Scroll path (`OSContentletScrollImpl`) unchanged (already correct). 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Proposed Changes
Two OpenSearch read-path gaps found running the integration suite under ES→OS migration phase 2 (reads from OpenSearch). Both have a working ES reference implementation. Contributes to #36501.
OSIndexProperty.TRACK_TOTAL_HITShad no ES fallback key, so an existingES_TRACK_TOTAL_HITSconfig was ignored under OS reads and OS always returned the full accurate count. Added theES_TRACK_TOTAL_HITSfallback (same dual-key pattern asUSE_FILTERS_FOR_SEARCHING).ContentFactoryIndexOperationsOS.addSorting, forsortBy=score, added only the secondary field sort and never a primary_scoresort, so results ordered by moddate and hit[0] was not the highest-scoring doc. Added the_score DESCprimary sort (mirrorsContentFactoryIndexOperationsES.addSorting; API matchesOSContentletScrollImpl).Verification
Phase 2, isolated env:
ESContentFactoryImplTest42/0/0 (incl.Test_TrackHits_SearchCountandtestScore, previously failing). Core compiles.Refs #36501, #36320.
This PR fixes: #36501