Skip to content

Leveraging segment-global ordinal mapping for efficient terms aggrega… - #20683

Merged
jainankitk merged 8 commits into
opensearch-project:mainfrom
jainankitk:fix-terms
Feb 23, 2026
Merged

Leveraging segment-global ordinal mapping for efficient terms aggrega…#20683
jainankitk merged 8 commits into
opensearch-project:mainfrom
jainankitk:fix-terms

Conversation

@jainankitk

Copy link
Copy Markdown
Contributor

…tion

Description

Address the terms aggregation performance regression using segment to global ordinals mapping without reading the terms from disk for per segment collection

Related Issues

Resolves #20626

Check List

  • Functionality includes testing.
  • API changes companion pull request created, if applicable.
  • Public documentation issue/PR created, if applicable.

By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 license.
For more information on following Developer Certificate of Origin and signing off your commits, please check here.

@coderabbitai

coderabbitai Bot commented Feb 20, 2026

Copy link
Copy Markdown
Contributor

Important

Review skipped

Auto incremental reviews are disabled on this repository.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

Refactors the term-frequency collection loop in GlobalOrdinalsStringTermsAggregator.tryCollectFromTermFrequencies to iterate only through segment terms while using a global ordinals mapping to derive ordinals, replacing the previous leap-frogging two-iterator approach that unnecessarily iterated through all global ordinals per segment.

Changes

Cohort / File(s) Summary
Ordinals Mapping Optimization
server/src/main/java/org/opensearch/search/aggregations/bucket/terms/GlobalOrdinalsStringTermsAggregator.java
Replaced leap-frogging algorithm with segment-driven iteration using valuesSource.globalOrdinalsMapping(ctx) to map segment ordinals to global ordinals. Consolidates two nested iterator loops into a single segmentTermsEnum loop that conditionally increments counts when global ordinals are accepted. Adds import for DocIdSetIterator.NO_MORE_DOCS.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~12 minutes

Possibly related PRs

  • #20623: Also modifies GlobalOrdinalsStringTermsAggregator.tryCollectFromTermFrequencies to add cardinality threshold preconditions for skipping high-cardinality segments.

Suggested labels

v3.5.0, backport 3.5

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The PR title clearly summarizes the main change: leveraging segment-global ordinal mapping for efficient terms aggregation, which directly reflects the core refactoring described in the changeset.
Description check ✅ Passed The PR description addresses the template requirements with a clear description of the change, linked issue #20626, and a completed checklist confirming testing is included.
Linked Issues check ✅ Passed The code changes directly address the linked issue #20626 by replacing the leap-frogging algorithm with segment-driven term iteration and global ordinal mapping, eliminating the performance regression caused by iterating through millions of non-matching global ordinals.
Out of Scope Changes check ✅ Passed All code changes are scoped to the specific optimization described in the linked issue: refactoring GlobalOrdinalsStringTermsAggregator.tryCollectFromTermFrequencies to use segment-global ordinal mapping instead of the leap-frogging algorithm.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

Comment @coderabbitai help to get the list of available commands and usage tips.

@coderabbitai coderabbitai Bot 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.

Actionable comments posted: 2

📜 Review details

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 107aa53 and b7a981d.

📒 Files selected for processing (1)
  • server/src/main/java/org/opensearch/search/aggregations/bucket/terms/GlobalOrdinalsStringTermsAggregator.java
🧰 Additional context used
🧠 Learnings (1)
📚 Learning: 2026-01-13T17:40:27.167Z
Learnt from: reta
Repo: opensearch-project/OpenSearch PR: 20411
File: server/src/main/java/org/opensearch/index/codec/CodecService.java:112-133
Timestamp: 2026-01-13T17:40:27.167Z
Learning: Avoid capturing or evaluating a supplier (e.g., this::defaultCodec) upfront when passing it to a registry during object construction. If registries may replace defaults during iteration (as in EnginePlugin.getAdditionalCodecs), pass the supplier itself and only resolve it at use time. This ensures dynamic behavior is preserved during initialization and prevents premature binding of defaults in codecs/registry setup. This pattern should apply to similar initialization paths in Java server code where registries may mutate defaults during construction.

Applied to files:

  • server/src/main/java/org/opensearch/search/aggregations/bucket/terms/GlobalOrdinalsStringTermsAggregator.java
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (20)
  • GitHub Check: gradle-check
  • GitHub Check: precommit (21, ubuntu-24.04-arm)
  • GitHub Check: precommit (21, macos-15-intel)
  • GitHub Check: precommit (25, macos-15)
  • GitHub Check: precommit (21, macos-15)
  • GitHub Check: precommit (25, ubuntu-latest)
  • GitHub Check: precommit (21, windows-latest)
  • GitHub Check: precommit (21, windows-2025, true)
  • GitHub Check: precommit (25, windows-latest)
  • GitHub Check: precommit (25, ubuntu-24.04-arm)
  • GitHub Check: precommit (25, macos-15-intel)
  • GitHub Check: precommit (21, ubuntu-latest)
  • GitHub Check: detect-breaking-change
  • GitHub Check: assemble (25, ubuntu-24.04-arm)
  • GitHub Check: assemble (21, ubuntu-latest)
  • GitHub Check: Analyze (java)
  • GitHub Check: assemble (21, ubuntu-24.04-arm)
  • GitHub Check: assemble (25, ubuntu-latest)
  • GitHub Check: assemble (21, windows-latest)
  • GitHub Check: assemble (25, windows-latest)
🔇 Additional comments (1)
server/src/main/java/org/opensearch/search/aggregations/bucket/terms/GlobalOrdinalsStringTermsAggregator.java (1)

218-218: The ordinal mapping pattern at line 218 is sound. GlobalOrdinalsIndexFieldData explicitly documents that segment TermsEnum ordinals are designed to work with the OrdinalMap for global ordinals retrieval. The code is restricted to ValuesSource.Bytes.WithOrdinals (keyword and IP fields), where both inverted index and doc values ordinals are lexicographically sorted and compatible. No verification needed—this is a supported framework pattern.

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In
`@server/src/main/java/org/opensearch/search/aggregations/bucket/terms/GlobalOrdinalsStringTermsAggregator.java`:
- Around line 94-95: The duplicate static import of NO_MORE_DOCS causes
ambiguous reference errors in GlobalOrdinalsStringTermsAggregator; remove the
deprecated static import of SortedSetDocValues.NO_MORE_DOCS and keep the static
import from DocIdSetIterator.NO_MORE_DOCS so unqualified uses of NO_MORE_DOCS
(e.g., in methods referencing NO_MORE_DOCS) resolve to
DocIdSetIterator.NO_MORE_DOCS; update the import block to drop the
SortedSetDocValues static import and ensure any references to
SortedSetDocValues.NO_MORE_DOCS are either removed or explicitly qualified to
DocIdSetIterator.NO_MORE_DOCS if needed.
- Around line 211-223: The loop in GlobalOrdinalsStringTermsAggregator now
passes global ordinals into ordCountConsumer, but
LowCardinality.tryPrecomputeAggregationForLeaf still assumes it will receive
segment ordinals and calls mapping.applyAsLong(ord), causing double-mapping;
update LowCardinality.tryPrecomputeAggregationForLeaf to accept the global
ordinal directly (i.e., stop calling mapping.applyAsLong on the ord passed into
the lambda) so it forwards the global ord to incrementBucketDocCount, and ensure
any references to mapping.applyAsLong in that method are removed or gated so
they only run when the incoming ord is a segment ord.

@github-actions

Copy link
Copy Markdown
Contributor

❌ Gradle check result for b7a981d: FAILURE

Please examine the workflow log, locate, and copy-paste the failure(s) below, then iterate to green. Is the failure a flaky test unrelated to your change?

@github-actions

Copy link
Copy Markdown
Contributor

❌ Gradle check result for a480f25: FAILURE

Please examine the workflow log, locate, and copy-paste the failure(s) below, then iterate to green. Is the failure a flaky test unrelated to your change?

@github-actions

Copy link
Copy Markdown
Contributor

✅ Gradle check result for 5a1f4c0: SUCCESS

@codecov

codecov Bot commented Feb 20, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 80.00000% with 2 lines in your changes missing coverage. Please review.
✅ Project coverage is 73.30%. Comparing base (6b557db) to head (3e78591).
⚠️ Report is 14 commits behind head on main.

Files with missing lines Patch % Lines
...ket/terms/GlobalOrdinalsStringTermsAggregator.java 80.00% 0 Missing and 2 partials ⚠️
Additional details and impacted files
@@             Coverage Diff              @@
##               main   #20683      +/-   ##
============================================
- Coverage     73.32%   73.30%   -0.03%     
+ Complexity    72064    72009      -55     
============================================
  Files          5781     5781              
  Lines        329395   329392       -3     
  Branches      47525    47524       -1     
============================================
- Hits         241536   241448      -88     
- Misses        68507    68543      +36     
- Partials      19352    19401      +49     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

Signed-off-by: Ankit Jain <jainankitk@apache.org>
Signed-off-by: Ankit Jain <jainankitk@apache.org>
@github-actions

Copy link
Copy Markdown
Contributor

Persistent review updated to latest commit bf39ece

@github-actions

Copy link
Copy Markdown
Contributor

Persistent review updated to latest commit 48cad83

…rmance"

This reverts commit 0e0882c.

Signed-off-by: Ankit Jain <jainankitk@apache.org>
@github-actions

Copy link
Copy Markdown
Contributor

Persistent review updated to latest commit 0e0882c

Signed-off-by: Ankit Jain <jainankitk@apache.org>
@github-actions

Copy link
Copy Markdown
Contributor

Persistent review updated to latest commit 3e78591

@github-actions

Copy link
Copy Markdown
Contributor

✅ Gradle check result for 3e78591: SUCCESS

@jainankitk
jainankitk merged commit 854f882 into opensearch-project:main Feb 23, 2026
35 checks passed
@jainankitk
jainankitk deleted the fix-terms branch February 23, 2026 19:03
@jainankitk jainankitk added the backport 3.5 Backport to 3.5 branch label Feb 23, 2026
opensearch-trigger-bot Bot pushed a commit that referenced this pull request Feb 23, 2026
#20683)

Signed-off-by: Ankit Jain <jainankitk@apache.org>
(cherry picked from commit 854f882)
Signed-off-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
aparajita31pandey pushed a commit to aparajita31pandey/OpenSearch that referenced this pull request Apr 18, 2026
opensearch-project#20683)

Signed-off-by: Ankit Jain <jainankitk@apache.org>
Signed-off-by: Aparajita Pandey <aparajita31pandey@gmail.com>
pradeep-L pushed a commit to pradeep-L/OpenSearch that referenced this pull request Apr 21, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

backport 3.5 Backport to 3.5 branch bug Something isn't working Search:Performance skip-diff-analyzer Maintainer to skip code-diff-analyzer check, after reviewing issues in AI analysis.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Performance regression in terms aggregation with match_all queries

5 participants